diff options
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r-- | crates/ra_lsp_server/src/project_model.rs | 251 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model/cargo_workspace.rs | 173 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model/sysroot.rs | 78 |
3 files changed, 261 insertions, 241 deletions
diff --git a/crates/ra_lsp_server/src/project_model.rs b/crates/ra_lsp_server/src/project_model.rs index 6fbaba7d9..3d02c6549 100644 --- a/crates/ra_lsp_server/src/project_model.rs +++ b/crates/ra_lsp_server/src/project_model.rs | |||
@@ -1,17 +1,20 @@ | |||
1 | mod cargo_workspace; | ||
2 | mod sysroot; | ||
3 | |||
1 | use std::{ | 4 | use std::{ |
2 | path::{Path, PathBuf}, | 5 | path::{Path, PathBuf}, |
3 | process::Command, | ||
4 | }; | 6 | }; |
5 | 7 | ||
6 | use cargo_metadata::{metadata_run, CargoOpt}; | 8 | use failure::bail; |
7 | use ra_syntax::SmolStr; | ||
8 | use ra_arena::{Arena, RawId, impl_arena_id}; | ||
9 | use rustc_hash::FxHashMap; | ||
10 | use failure::{format_err, bail}; | ||
11 | use thread_worker::{WorkerHandle, Worker}; | 9 | use thread_worker::{WorkerHandle, Worker}; |
12 | 10 | ||
13 | use crate::Result; | 11 | use crate::Result; |
14 | 12 | ||
13 | pub use crate::project_model::{ | ||
14 | cargo_workspace::{CargoWorkspace, Package, Target, TargetKind}, | ||
15 | sysroot::Sysroot, | ||
16 | }; | ||
17 | |||
15 | #[derive(Debug, Clone)] | 18 | #[derive(Debug, Clone)] |
16 | pub struct ProjectWorkspace { | 19 | pub struct ProjectWorkspace { |
17 | pub(crate) cargo: CargoWorkspace, | 20 | pub(crate) cargo: CargoWorkspace, |
@@ -22,7 +25,7 @@ impl ProjectWorkspace { | |||
22 | pub fn discover(path: &Path) -> Result<ProjectWorkspace> { | 25 | pub fn discover(path: &Path) -> Result<ProjectWorkspace> { |
23 | let cargo_toml = find_cargo_toml(path)?; | 26 | let cargo_toml = find_cargo_toml(path)?; |
24 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?; | 27 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?; |
25 | let sysroot = sysroot_info(&cargo_toml)?; | 28 | let sysroot = Sysroot::discover(&cargo_toml)?; |
26 | let res = ProjectWorkspace { cargo, sysroot }; | 29 | let res = ProjectWorkspace { cargo, sysroot }; |
27 | Ok(res) | 30 | Ok(res) |
28 | } | 31 | } |
@@ -42,224 +45,6 @@ pub fn workspace_loader() -> (Worker<PathBuf, Result<ProjectWorkspace>>, WorkerH | |||
42 | ) | 45 | ) |
43 | } | 46 | } |
44 | 47 | ||
45 | /// `CargoWorksapce` represents the logical structure of, well, a Cargo | ||
46 | /// workspace. It pretty closely mirrors `cargo metadata` output. | ||
47 | /// | ||
48 | /// Note that internally, rust analyzer uses a differnet structure: | ||
49 | /// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, | ||
50 | /// while this knows about `Pacakges` & `Targets`: purely cargo-related | ||
51 | /// concepts. | ||
52 | #[derive(Debug, Clone)] | ||
53 | pub struct CargoWorkspace { | ||
54 | packages: Arena<Package, PackageData>, | ||
55 | targets: Arena<Target, TargetData>, | ||
56 | } | ||
57 | |||
58 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
59 | pub struct Package(RawId); | ||
60 | impl_arena_id!(Package); | ||
61 | |||
62 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
63 | pub struct Target(RawId); | ||
64 | impl_arena_id!(Target); | ||
65 | |||
66 | #[derive(Debug, Clone)] | ||
67 | struct PackageData { | ||
68 | name: SmolStr, | ||
69 | manifest: PathBuf, | ||
70 | targets: Vec<Target>, | ||
71 | is_member: bool, | ||
72 | dependencies: Vec<PackageDependency>, | ||
73 | } | ||
74 | |||
75 | #[derive(Debug, Clone)] | ||
76 | pub struct PackageDependency { | ||
77 | pub pkg: Package, | ||
78 | pub name: SmolStr, | ||
79 | } | ||
80 | |||
81 | #[derive(Debug, Clone)] | ||
82 | struct TargetData { | ||
83 | pkg: Package, | ||
84 | name: SmolStr, | ||
85 | root: PathBuf, | ||
86 | kind: TargetKind, | ||
87 | } | ||
88 | |||
89 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
90 | pub enum TargetKind { | ||
91 | Bin, | ||
92 | Lib, | ||
93 | Example, | ||
94 | Test, | ||
95 | Bench, | ||
96 | Other, | ||
97 | } | ||
98 | |||
99 | #[derive(Debug, Clone)] | ||
100 | pub(crate) struct Sysroot { | ||
101 | crates: FxHashMap<SmolStr, PathBuf>, | ||
102 | } | ||
103 | |||
104 | impl Package { | ||
105 | pub fn name(self, ws: &CargoWorkspace) -> &str { | ||
106 | ws.packages[self].name.as_str() | ||
107 | } | ||
108 | pub fn root(self, ws: &CargoWorkspace) -> &Path { | ||
109 | ws.packages[self].manifest.parent().unwrap() | ||
110 | } | ||
111 | pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator<Item = Target> + 'a { | ||
112 | ws.packages[self].targets.iter().cloned() | ||
113 | } | ||
114 | #[allow(unused)] | ||
115 | pub fn is_member(self, ws: &CargoWorkspace) -> bool { | ||
116 | ws.packages[self].is_member | ||
117 | } | ||
118 | pub fn dependencies<'a>( | ||
119 | self, | ||
120 | ws: &'a CargoWorkspace, | ||
121 | ) -> impl Iterator<Item = &'a PackageDependency> + 'a { | ||
122 | ws.packages[self].dependencies.iter() | ||
123 | } | ||
124 | } | ||
125 | |||
126 | impl Target { | ||
127 | pub fn package(self, ws: &CargoWorkspace) -> Package { | ||
128 | ws.targets[self].pkg | ||
129 | } | ||
130 | pub fn name(self, ws: &CargoWorkspace) -> &str { | ||
131 | ws.targets[self].name.as_str() | ||
132 | } | ||
133 | pub fn root(self, ws: &CargoWorkspace) -> &Path { | ||
134 | ws.targets[self].root.as_path() | ||
135 | } | ||
136 | pub fn kind(self, ws: &CargoWorkspace) -> TargetKind { | ||
137 | ws.targets[self].kind | ||
138 | } | ||
139 | } | ||
140 | |||
141 | impl CargoWorkspace { | ||
142 | pub fn from_cargo_metadata(path: &Path) -> Result<CargoWorkspace> { | ||
143 | let cargo_toml = find_cargo_toml(path)?; | ||
144 | let meta = metadata_run( | ||
145 | Some(cargo_toml.as_path()), | ||
146 | true, | ||
147 | Some(CargoOpt::AllFeatures), | ||
148 | ) | ||
149 | .map_err(|e| format_err!("cargo metadata failed: {}", e))?; | ||
150 | let mut pkg_by_id = FxHashMap::default(); | ||
151 | let mut packages = Arena::default(); | ||
152 | let mut targets = Arena::default(); | ||
153 | |||
154 | let ws_members = &meta.workspace_members; | ||
155 | |||
156 | for meta_pkg in meta.packages { | ||
157 | let is_member = ws_members.contains(&meta_pkg.id); | ||
158 | let pkg = packages.alloc(PackageData { | ||
159 | name: meta_pkg.name.into(), | ||
160 | manifest: meta_pkg.manifest_path.clone(), | ||
161 | targets: Vec::new(), | ||
162 | is_member, | ||
163 | dependencies: Vec::new(), | ||
164 | }); | ||
165 | let pkg_data = &mut packages[pkg]; | ||
166 | pkg_by_id.insert(meta_pkg.id.clone(), pkg); | ||
167 | for meta_tgt in meta_pkg.targets { | ||
168 | let tgt = targets.alloc(TargetData { | ||
169 | pkg, | ||
170 | name: meta_tgt.name.into(), | ||
171 | root: meta_tgt.src_path.clone(), | ||
172 | kind: TargetKind::new(meta_tgt.kind.as_slice()), | ||
173 | }); | ||
174 | pkg_data.targets.push(tgt); | ||
175 | } | ||
176 | } | ||
177 | let resolve = meta.resolve.expect("metadata executed with deps"); | ||
178 | for node in resolve.nodes { | ||
179 | let source = pkg_by_id[&node.id]; | ||
180 | for dep_node in node.deps { | ||
181 | let dep = PackageDependency { | ||
182 | name: dep_node.name.into(), | ||
183 | pkg: pkg_by_id[&dep_node.pkg], | ||
184 | }; | ||
185 | packages[source].dependencies.push(dep); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | Ok(CargoWorkspace { packages, targets }) | ||
190 | } | ||
191 | pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + 'a { | ||
192 | self.packages.iter().map(|(id, _pkg)| id) | ||
193 | } | ||
194 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { | ||
195 | self.packages() | ||
196 | .filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)) | ||
197 | .next() | ||
198 | } | ||
199 | } | ||
200 | |||
201 | fn sysroot_info(cargo_toml: &Path) -> Result<Sysroot> { | ||
202 | let rustc_output = Command::new("rustc") | ||
203 | .current_dir(cargo_toml.parent().unwrap()) | ||
204 | .args(&["--print", "sysroot"]) | ||
205 | .output()?; | ||
206 | if !rustc_output.status.success() { | ||
207 | failure::bail!("failed to locate sysroot") | ||
208 | } | ||
209 | let stdout = String::from_utf8(rustc_output.stdout)?; | ||
210 | let sysroot_path = Path::new(stdout.trim()); | ||
211 | let src = sysroot_path.join("lib/rustlib/src/rust/src"); | ||
212 | |||
213 | let crates: &[(&str, &[&str])] = &[ | ||
214 | ( | ||
215 | "std", | ||
216 | &[ | ||
217 | "alloc_jemalloc", | ||
218 | "alloc_system", | ||
219 | "panic_abort", | ||
220 | "rand", | ||
221 | "compiler_builtins", | ||
222 | "unwind", | ||
223 | "rustc_asan", | ||
224 | "rustc_lsan", | ||
225 | "rustc_msan", | ||
226 | "rustc_tsan", | ||
227 | "build_helper", | ||
228 | ], | ||
229 | ), | ||
230 | ("core", &[]), | ||
231 | ("alloc", &[]), | ||
232 | ("collections", &[]), | ||
233 | ("libc", &[]), | ||
234 | ("panic_unwind", &[]), | ||
235 | ("proc_macro", &[]), | ||
236 | ("rustc_unicode", &[]), | ||
237 | ("std_unicode", &[]), | ||
238 | ("test", &[]), | ||
239 | // Feature gated | ||
240 | ("alloc_jemalloc", &[]), | ||
241 | ("alloc_system", &[]), | ||
242 | ("compiler_builtins", &[]), | ||
243 | ("getopts", &[]), | ||
244 | ("panic_unwind", &[]), | ||
245 | ("panic_abort", &[]), | ||
246 | ("rand", &[]), | ||
247 | ("term", &[]), | ||
248 | ("unwind", &[]), | ||
249 | // Dependencies | ||
250 | ("build_helper", &[]), | ||
251 | ("rustc_asan", &[]), | ||
252 | ("rustc_lsan", &[]), | ||
253 | ("rustc_msan", &[]), | ||
254 | ("rustc_tsan", &[]), | ||
255 | ("syntax", &[]), | ||
256 | ]; | ||
257 | |||
258 | Ok(Sysroot { | ||
259 | crates: FxHashMap::default(), | ||
260 | }) | ||
261 | } | ||
262 | |||
263 | fn find_cargo_toml(path: &Path) -> Result<PathBuf> { | 48 | fn find_cargo_toml(path: &Path) -> Result<PathBuf> { |
264 | if path.ends_with("Cargo.toml") { | 49 | if path.ends_with("Cargo.toml") { |
265 | return Ok(path.to_path_buf()); | 50 | return Ok(path.to_path_buf()); |
@@ -274,19 +59,3 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf> { | |||
274 | } | 59 | } |
275 | bail!("can't find Cargo.toml at {}", path.display()) | 60 | bail!("can't find Cargo.toml at {}", path.display()) |
276 | } | 61 | } |
277 | |||
278 | impl TargetKind { | ||
279 | fn new(kinds: &[String]) -> TargetKind { | ||
280 | for kind in kinds { | ||
281 | return match kind.as_str() { | ||
282 | "bin" => TargetKind::Bin, | ||
283 | "test" => TargetKind::Test, | ||
284 | "bench" => TargetKind::Bench, | ||
285 | "example" => TargetKind::Example, | ||
286 | _ if kind.contains("lib") => TargetKind::Lib, | ||
287 | _ => continue, | ||
288 | }; | ||
289 | } | ||
290 | TargetKind::Other | ||
291 | } | ||
292 | } | ||
diff --git a/crates/ra_lsp_server/src/project_model/cargo_workspace.rs b/crates/ra_lsp_server/src/project_model/cargo_workspace.rs index e69de29bb..138fdee22 100644 --- a/crates/ra_lsp_server/src/project_model/cargo_workspace.rs +++ b/crates/ra_lsp_server/src/project_model/cargo_workspace.rs | |||
@@ -0,0 +1,173 @@ | |||
1 | use std::{ | ||
2 | path::{Path, PathBuf}, | ||
3 | }; | ||
4 | |||
5 | use cargo_metadata::{metadata_run, CargoOpt}; | ||
6 | use ra_syntax::SmolStr; | ||
7 | use ra_arena::{Arena, RawId, impl_arena_id}; | ||
8 | use rustc_hash::FxHashMap; | ||
9 | use failure::format_err; | ||
10 | |||
11 | use crate::Result; | ||
12 | |||
13 | /// `CargoWorksapce` represents the logical structure of, well, a Cargo | ||
14 | /// workspace. It pretty closely mirrors `cargo metadata` output. | ||
15 | /// | ||
16 | /// Note that internally, rust analyzer uses a differnet structure: | ||
17 | /// `CrateGraph`. `CrateGraph` is lower-level: it knows only about the crates, | ||
18 | /// while this knows about `Pacakges` & `Targets`: purely cargo-related | ||
19 | /// concepts. | ||
20 | #[derive(Debug, Clone)] | ||
21 | pub struct CargoWorkspace { | ||
22 | packages: Arena<Package, PackageData>, | ||
23 | targets: Arena<Target, TargetData>, | ||
24 | } | ||
25 | |||
26 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
27 | pub struct Package(RawId); | ||
28 | impl_arena_id!(Package); | ||
29 | |||
30 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
31 | pub struct Target(RawId); | ||
32 | impl_arena_id!(Target); | ||
33 | |||
34 | #[derive(Debug, Clone)] | ||
35 | struct PackageData { | ||
36 | name: SmolStr, | ||
37 | manifest: PathBuf, | ||
38 | targets: Vec<Target>, | ||
39 | is_member: bool, | ||
40 | dependencies: Vec<PackageDependency>, | ||
41 | } | ||
42 | |||
43 | #[derive(Debug, Clone)] | ||
44 | pub struct PackageDependency { | ||
45 | pub pkg: Package, | ||
46 | pub name: SmolStr, | ||
47 | } | ||
48 | |||
49 | #[derive(Debug, Clone)] | ||
50 | struct TargetData { | ||
51 | pkg: Package, | ||
52 | name: SmolStr, | ||
53 | root: PathBuf, | ||
54 | kind: TargetKind, | ||
55 | } | ||
56 | |||
57 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
58 | pub enum TargetKind { | ||
59 | Bin, | ||
60 | Lib, | ||
61 | Example, | ||
62 | Test, | ||
63 | Bench, | ||
64 | Other, | ||
65 | } | ||
66 | |||
67 | impl TargetKind { | ||
68 | fn new(kinds: &[String]) -> TargetKind { | ||
69 | for kind in kinds { | ||
70 | return match kind.as_str() { | ||
71 | "bin" => TargetKind::Bin, | ||
72 | "test" => TargetKind::Test, | ||
73 | "bench" => TargetKind::Bench, | ||
74 | "example" => TargetKind::Example, | ||
75 | _ if kind.contains("lib") => TargetKind::Lib, | ||
76 | _ => continue, | ||
77 | }; | ||
78 | } | ||
79 | TargetKind::Other | ||
80 | } | ||
81 | } | ||
82 | |||
83 | impl Package { | ||
84 | pub fn name(self, ws: &CargoWorkspace) -> &str { | ||
85 | ws.packages[self].name.as_str() | ||
86 | } | ||
87 | pub fn root(self, ws: &CargoWorkspace) -> &Path { | ||
88 | ws.packages[self].manifest.parent().unwrap() | ||
89 | } | ||
90 | pub fn targets<'a>(self, ws: &'a CargoWorkspace) -> impl Iterator<Item = Target> + 'a { | ||
91 | ws.packages[self].targets.iter().cloned() | ||
92 | } | ||
93 | #[allow(unused)] | ||
94 | pub fn is_member(self, ws: &CargoWorkspace) -> bool { | ||
95 | ws.packages[self].is_member | ||
96 | } | ||
97 | pub fn dependencies<'a>( | ||
98 | self, | ||
99 | ws: &'a CargoWorkspace, | ||
100 | ) -> impl Iterator<Item = &'a PackageDependency> + 'a { | ||
101 | ws.packages[self].dependencies.iter() | ||
102 | } | ||
103 | } | ||
104 | |||
105 | impl Target { | ||
106 | pub fn package(self, ws: &CargoWorkspace) -> Package { | ||
107 | ws.targets[self].pkg | ||
108 | } | ||
109 | pub fn name(self, ws: &CargoWorkspace) -> &str { | ||
110 | ws.targets[self].name.as_str() | ||
111 | } | ||
112 | pub fn root(self, ws: &CargoWorkspace) -> &Path { | ||
113 | ws.targets[self].root.as_path() | ||
114 | } | ||
115 | pub fn kind(self, ws: &CargoWorkspace) -> TargetKind { | ||
116 | ws.targets[self].kind | ||
117 | } | ||
118 | } | ||
119 | |||
120 | impl CargoWorkspace { | ||
121 | pub fn from_cargo_metadata(cargo_toml: &Path) -> Result<CargoWorkspace> { | ||
122 | let meta = metadata_run(Some(cargo_toml), true, Some(CargoOpt::AllFeatures)) | ||
123 | .map_err(|e| format_err!("cargo metadata failed: {}", e))?; | ||
124 | let mut pkg_by_id = FxHashMap::default(); | ||
125 | let mut packages = Arena::default(); | ||
126 | let mut targets = Arena::default(); | ||
127 | |||
128 | let ws_members = &meta.workspace_members; | ||
129 | |||
130 | for meta_pkg in meta.packages { | ||
131 | let is_member = ws_members.contains(&meta_pkg.id); | ||
132 | let pkg = packages.alloc(PackageData { | ||
133 | name: meta_pkg.name.into(), | ||
134 | manifest: meta_pkg.manifest_path.clone(), | ||
135 | targets: Vec::new(), | ||
136 | is_member, | ||
137 | dependencies: Vec::new(), | ||
138 | }); | ||
139 | let pkg_data = &mut packages[pkg]; | ||
140 | pkg_by_id.insert(meta_pkg.id.clone(), pkg); | ||
141 | for meta_tgt in meta_pkg.targets { | ||
142 | let tgt = targets.alloc(TargetData { | ||
143 | pkg, | ||
144 | name: meta_tgt.name.into(), | ||
145 | root: meta_tgt.src_path.clone(), | ||
146 | kind: TargetKind::new(meta_tgt.kind.as_slice()), | ||
147 | }); | ||
148 | pkg_data.targets.push(tgt); | ||
149 | } | ||
150 | } | ||
151 | let resolve = meta.resolve.expect("metadata executed with deps"); | ||
152 | for node in resolve.nodes { | ||
153 | let source = pkg_by_id[&node.id]; | ||
154 | for dep_node in node.deps { | ||
155 | let dep = PackageDependency { | ||
156 | name: dep_node.name.into(), | ||
157 | pkg: pkg_by_id[&dep_node.pkg], | ||
158 | }; | ||
159 | packages[source].dependencies.push(dep); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | Ok(CargoWorkspace { packages, targets }) | ||
164 | } | ||
165 | pub fn packages<'a>(&'a self) -> impl Iterator<Item = Package> + 'a { | ||
166 | self.packages.iter().map(|(id, _pkg)| id) | ||
167 | } | ||
168 | pub fn target_by_root(&self, root: &Path) -> Option<Target> { | ||
169 | self.packages() | ||
170 | .filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)) | ||
171 | .next() | ||
172 | } | ||
173 | } | ||
diff --git a/crates/ra_lsp_server/src/project_model/sysroot.rs b/crates/ra_lsp_server/src/project_model/sysroot.rs index e69de29bb..ae72c9c17 100644 --- a/crates/ra_lsp_server/src/project_model/sysroot.rs +++ b/crates/ra_lsp_server/src/project_model/sysroot.rs | |||
@@ -0,0 +1,78 @@ | |||
1 | use std::{ | ||
2 | path::{Path, PathBuf}, | ||
3 | process::Command, | ||
4 | }; | ||
5 | |||
6 | use ra_syntax::SmolStr; | ||
7 | use rustc_hash::FxHashMap; | ||
8 | |||
9 | use crate::Result; | ||
10 | |||
11 | #[derive(Debug, Clone)] | ||
12 | pub struct Sysroot { | ||
13 | crates: FxHashMap<SmolStr, PathBuf>, | ||
14 | } | ||
15 | |||
16 | impl Sysroot { | ||
17 | pub(crate) fn discover(cargo_toml: &Path) -> Result<Sysroot> { | ||
18 | let rustc_output = Command::new("rustc") | ||
19 | .current_dir(cargo_toml.parent().unwrap()) | ||
20 | .args(&["--print", "sysroot"]) | ||
21 | .output()?; | ||
22 | if !rustc_output.status.success() { | ||
23 | failure::bail!("failed to locate sysroot") | ||
24 | } | ||
25 | let stdout = String::from_utf8(rustc_output.stdout)?; | ||
26 | let sysroot_path = Path::new(stdout.trim()); | ||
27 | let src = sysroot_path.join("lib/rustlib/src/rust/src"); | ||
28 | |||
29 | let crates: &[(&str, &[&str])] = &[ | ||
30 | ( | ||
31 | "std", | ||
32 | &[ | ||
33 | "alloc_jemalloc", | ||
34 | "alloc_system", | ||
35 | "panic_abort", | ||
36 | "rand", | ||
37 | "compiler_builtins", | ||
38 | "unwind", | ||
39 | "rustc_asan", | ||
40 | "rustc_lsan", | ||
41 | "rustc_msan", | ||
42 | "rustc_tsan", | ||
43 | "build_helper", | ||
44 | ], | ||
45 | ), | ||
46 | ("core", &[]), | ||
47 | ("alloc", &[]), | ||
48 | ("collections", &[]), | ||
49 | ("libc", &[]), | ||
50 | ("panic_unwind", &[]), | ||
51 | ("proc_macro", &[]), | ||
52 | ("rustc_unicode", &[]), | ||
53 | ("std_unicode", &[]), | ||
54 | ("test", &[]), | ||
55 | // Feature gated | ||
56 | ("alloc_jemalloc", &[]), | ||
57 | ("alloc_system", &[]), | ||
58 | ("compiler_builtins", &[]), | ||
59 | ("getopts", &[]), | ||
60 | ("panic_unwind", &[]), | ||
61 | ("panic_abort", &[]), | ||
62 | ("rand", &[]), | ||
63 | ("term", &[]), | ||
64 | ("unwind", &[]), | ||
65 | // Dependencies | ||
66 | ("build_helper", &[]), | ||
67 | ("rustc_asan", &[]), | ||
68 | ("rustc_lsan", &[]), | ||
69 | ("rustc_msan", &[]), | ||
70 | ("rustc_tsan", &[]), | ||
71 | ("syntax", &[]), | ||
72 | ]; | ||
73 | |||
74 | Ok(Sysroot { | ||
75 | crates: FxHashMap::default(), | ||
76 | }) | ||
77 | } | ||
78 | } | ||