diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/base_db/src/input.rs | 20 | ||||
-rw-r--r-- | crates/project_model/src/sysroot.rs | 2 | ||||
-rw-r--r-- | crates/project_model/src/workspace.rs | 161 |
3 files changed, 75 insertions, 108 deletions
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs index 31907ed98..98ba372ad 100644 --- a/crates/base_db/src/input.rs +++ b/crates/base_db/src/input.rs | |||
@@ -225,7 +225,10 @@ impl CrateGraph { | |||
225 | to: CrateId, | 225 | to: CrateId, |
226 | ) -> Result<(), CyclicDependenciesError> { | 226 | ) -> Result<(), CyclicDependenciesError> { |
227 | if self.dfs_find(from, to, &mut FxHashSet::default()) { | 227 | if self.dfs_find(from, to, &mut FxHashSet::default()) { |
228 | return Err(CyclicDependenciesError); | 228 | return Err(CyclicDependenciesError { |
229 | from: (from, self[from].display_name.clone()), | ||
230 | to: (to, self[to].display_name.clone()), | ||
231 | }); | ||
229 | } | 232 | } |
230 | self.arena.get_mut(&from).unwrap().add_dep(name, to); | 233 | self.arena.get_mut(&from).unwrap().add_dep(name, to); |
231 | Ok(()) | 234 | Ok(()) |
@@ -421,7 +424,20 @@ impl fmt::Display for ParseEditionError { | |||
421 | impl std::error::Error for ParseEditionError {} | 424 | impl std::error::Error for ParseEditionError {} |
422 | 425 | ||
423 | #[derive(Debug)] | 426 | #[derive(Debug)] |
424 | pub struct CyclicDependenciesError; | 427 | pub struct CyclicDependenciesError { |
428 | from: (CrateId, Option<CrateDisplayName>), | ||
429 | to: (CrateId, Option<CrateDisplayName>), | ||
430 | } | ||
431 | |||
432 | impl fmt::Display for CyclicDependenciesError { | ||
433 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
434 | let render = |(id, name): &(CrateId, Option<CrateDisplayName>)| match name { | ||
435 | Some(it) => format!("{}({:?})", it, id), | ||
436 | None => format!("{:?}", id), | ||
437 | }; | ||
438 | write!(f, "cyclic deps: {} -> {}", render(&self.from), render(&self.to)) | ||
439 | } | ||
440 | } | ||
425 | 441 | ||
426 | #[cfg(test)] | 442 | #[cfg(test)] |
427 | mod tests { | 443 | mod tests { |
diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs index b0e8863f6..f0a43eaf6 100644 --- a/crates/project_model/src/sysroot.rs +++ b/crates/project_model/src/sysroot.rs | |||
@@ -37,7 +37,7 @@ impl Sysroot { | |||
37 | pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ { | 37 | pub fn public_deps(&self) -> impl Iterator<Item = (&'static str, SysrootCrate)> + '_ { |
38 | // core is added as a dependency before std in order to | 38 | // core is added as a dependency before std in order to |
39 | // mimic rustcs dependency order | 39 | // mimic rustcs dependency order |
40 | vec!["core", "alloc", "std"].into_iter().filter_map(move |it| Some((it, self.by_name(it)?))) | 40 | ["core", "alloc", "std"].iter().filter_map(move |&it| Some((it, self.by_name(it)?))) |
41 | } | 41 | } |
42 | 42 | ||
43 | pub fn proc_macro(&self) -> Option<SysrootCrate> { | 43 | pub fn proc_macro(&self) -> Option<SysrootCrate> { |
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 9ebb0a811..dbf1dc5bf 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs | |||
@@ -12,8 +12,8 @@ use proc_macro_api::ProcMacroClient; | |||
12 | use rustc_hash::{FxHashMap, FxHashSet}; | 12 | use rustc_hash::{FxHashMap, FxHashSet}; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | cargo_workspace, cfg_flag::CfgFlag, utf8_stdout, CargoConfig, CargoWorkspace, ProjectJson, | 15 | cargo_workspace, cfg_flag::CfgFlag, sysroot::SysrootCrate, utf8_stdout, CargoConfig, |
16 | ProjectManifest, Sysroot, TargetKind, | 16 | CargoWorkspace, ProjectJson, ProjectManifest, Sysroot, TargetKind, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | /// `PackageRoot` describes a package root folder. | 19 | /// `PackageRoot` describes a package root folder. |
@@ -70,12 +70,8 @@ impl ProjectWorkspace { | |||
70 | format!("Failed to deserialize json file {}", project_json.display()) | 70 | format!("Failed to deserialize json file {}", project_json.display()) |
71 | })?; | 71 | })?; |
72 | let project_location = project_json.parent().unwrap().to_path_buf(); | 72 | let project_location = project_json.parent().unwrap().to_path_buf(); |
73 | let project = ProjectJson::new(&project_location, data); | 73 | let project_json = ProjectJson::new(&project_location, data); |
74 | let sysroot = match &project.sysroot_src { | 74 | ProjectWorkspace::load_inline(project_json)? |
75 | Some(path) => Some(Sysroot::load(path)?), | ||
76 | None => None, | ||
77 | }; | ||
78 | ProjectWorkspace::Json { project, sysroot } | ||
79 | } | 75 | } |
80 | ProjectManifest::CargoToml(cargo_toml) => { | 76 | ProjectManifest::CargoToml(cargo_toml) => { |
81 | let cargo_version = utf8_stdout({ | 77 | let cargo_version = utf8_stdout({ |
@@ -150,43 +146,38 @@ impl ProjectWorkspace { | |||
150 | }) | 146 | }) |
151 | })) | 147 | })) |
152 | .collect::<Vec<_>>(), | 148 | .collect::<Vec<_>>(), |
153 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => { | 149 | ProjectWorkspace::Cargo { cargo, sysroot, rustc } => cargo |
154 | let roots = cargo | 150 | .packages() |
155 | .packages() | 151 | .map(|pkg| { |
156 | .map(|pkg| { | 152 | let is_member = cargo[pkg].is_member; |
157 | let is_member = cargo[pkg].is_member; | 153 | let pkg_root = cargo[pkg].root().to_path_buf(); |
158 | let pkg_root = cargo[pkg].root().to_path_buf(); | 154 | |
159 | 155 | let mut include = vec![pkg_root.clone()]; | |
160 | let mut include = vec![pkg_root.clone()]; | 156 | include.extend(cargo[pkg].out_dir.clone()); |
161 | include.extend(cargo[pkg].out_dir.clone()); | 157 | |
162 | 158 | let mut exclude = vec![pkg_root.join(".git")]; | |
163 | let mut exclude = vec![pkg_root.join(".git")]; | 159 | if is_member { |
164 | if is_member { | 160 | exclude.push(pkg_root.join("target")); |
165 | exclude.push(pkg_root.join("target")); | 161 | } else { |
166 | } else { | 162 | exclude.push(pkg_root.join("tests")); |
167 | exclude.push(pkg_root.join("tests")); | 163 | exclude.push(pkg_root.join("examples")); |
168 | exclude.push(pkg_root.join("examples")); | 164 | exclude.push(pkg_root.join("benches")); |
169 | exclude.push(pkg_root.join("benches")); | 165 | } |
170 | } | 166 | PackageRoot { is_member, include, exclude } |
171 | PackageRoot { is_member, include, exclude } | 167 | }) |
172 | }) | 168 | .chain(sysroot.crates().map(|krate| PackageRoot { |
173 | .chain(sysroot.crates().map(|krate| PackageRoot { | 169 | is_member: false, |
170 | include: vec![sysroot[krate].root_dir().to_path_buf()], | ||
171 | exclude: Vec::new(), | ||
172 | })) | ||
173 | .chain(rustc.into_iter().flat_map(|rustc| { | ||
174 | rustc.packages().map(move |krate| PackageRoot { | ||
174 | is_member: false, | 175 | is_member: false, |
175 | include: vec![sysroot[krate].root_dir().to_path_buf()], | 176 | include: vec![rustc[krate].root().to_path_buf()], |
176 | exclude: Vec::new(), | 177 | exclude: Vec::new(), |
177 | })); | 178 | }) |
178 | if let Some(rustc_packages) = rustc { | 179 | })) |
179 | roots | 180 | .collect(), |
180 | .chain(rustc_packages.packages().map(|krate| PackageRoot { | ||
181 | is_member: false, | ||
182 | include: vec![rustc_packages[krate].root().to_path_buf()], | ||
183 | exclude: Vec::new(), | ||
184 | })) | ||
185 | .collect() | ||
186 | } else { | ||
187 | roots.collect() | ||
188 | } | ||
189 | } | ||
190 | } | 181 | } |
191 | } | 182 | } |
192 | 183 | ||
@@ -258,18 +249,14 @@ impl ProjectWorkspace { | |||
258 | if let Some(&from) = crates.get(&from) { | 249 | if let Some(&from) = crates.get(&from) { |
259 | if let Some((public_deps, _proc_macro)) = &sysroot_dps { | 250 | if let Some((public_deps, _proc_macro)) = &sysroot_dps { |
260 | for (name, to) in public_deps.iter() { | 251 | for (name, to) in public_deps.iter() { |
261 | if let Err(_) = crate_graph.add_dep(from, name.clone(), *to) { | 252 | add_dep(&mut crate_graph, from, name.clone(), *to) |
262 | log::error!("cyclic dependency on {} for {:?}", name, from) | ||
263 | } | ||
264 | } | 253 | } |
265 | } | 254 | } |
266 | 255 | ||
267 | for dep in &krate.deps { | 256 | for dep in &krate.deps { |
268 | let to_crate_id = dep.crate_id; | 257 | let to_crate_id = dep.crate_id; |
269 | if let Some(&to) = crates.get(&to_crate_id) { | 258 | if let Some(&to) = crates.get(&to_crate_id) { |
270 | if let Err(_) = crate_graph.add_dep(from, dep.name.clone(), to) { | 259 | add_dep(&mut crate_graph, from, dep.name.clone(), to) |
271 | log::error!("cyclic dependency {:?} -> {:?}", from, to); | ||
272 | } | ||
273 | } | 260 | } |
274 | } | 261 | } |
275 | } | 262 | } |
@@ -308,16 +295,12 @@ impl ProjectWorkspace { | |||
308 | } | 295 | } |
309 | if cargo[tgt].is_proc_macro { | 296 | if cargo[tgt].is_proc_macro { |
310 | if let Some(proc_macro) = libproc_macro { | 297 | if let Some(proc_macro) = libproc_macro { |
311 | if let Err(_) = crate_graph.add_dep( | 298 | add_dep( |
299 | &mut crate_graph, | ||
312 | crate_id, | 300 | crate_id, |
313 | CrateName::new("proc_macro").unwrap(), | 301 | CrateName::new("proc_macro").unwrap(), |
314 | proc_macro, | 302 | proc_macro, |
315 | ) { | 303 | ); |
316 | log::error!( | ||
317 | "cyclic dependency on proc_macro for {}", | ||
318 | &cargo[pkg].name | ||
319 | ) | ||
320 | } | ||
321 | } | 304 | } |
322 | } | 305 | } |
323 | 306 | ||
@@ -332,21 +315,12 @@ impl ProjectWorkspace { | |||
332 | // cargo metadata does not do any normalization, | 315 | // cargo metadata does not do any normalization, |
333 | // so we do it ourselves currently | 316 | // so we do it ourselves currently |
334 | let name = CrateName::normalize_dashes(&name); | 317 | let name = CrateName::normalize_dashes(&name); |
335 | if to != from && crate_graph.add_dep(from, name, to).is_err() { | 318 | if to != from { |
336 | log::error!( | 319 | add_dep(&mut crate_graph, from, name, to); |
337 | "cyclic dependency between targets of {}", | ||
338 | &cargo[pkg].name | ||
339 | ) | ||
340 | } | 320 | } |
341 | } | 321 | } |
342 | for (name, krate) in public_deps.iter() { | 322 | for (name, krate) in public_deps.iter() { |
343 | if let Err(_) = crate_graph.add_dep(from, name.clone(), *krate) { | 323 | add_dep(&mut crate_graph, from, name.clone(), *krate); |
344 | log::error!( | ||
345 | "cyclic dependency on {} for {}", | ||
346 | name, | ||
347 | &cargo[pkg].name | ||
348 | ) | ||
349 | } | ||
350 | } | 324 | } |
351 | } | 325 | } |
352 | } | 326 | } |
@@ -358,13 +332,7 @@ impl ProjectWorkspace { | |||
358 | let name = CrateName::new(&dep.name).unwrap(); | 332 | let name = CrateName::new(&dep.name).unwrap(); |
359 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { | 333 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { |
360 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 334 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { |
361 | if let Err(_) = crate_graph.add_dep(from, name.clone(), to) { | 335 | add_dep(&mut crate_graph, from, name.clone(), to) |
362 | log::error!( | ||
363 | "cyclic dependency {} -> {}", | ||
364 | &cargo[pkg].name, | ||
365 | &cargo[dep.pkg].name | ||
366 | ) | ||
367 | } | ||
368 | } | 336 | } |
369 | } | 337 | } |
370 | } | 338 | } |
@@ -400,15 +368,7 @@ impl ProjectWorkspace { | |||
400 | pkg_to_lib_crate.insert(pkg, crate_id); | 368 | pkg_to_lib_crate.insert(pkg, crate_id); |
401 | // Add dependencies on the core / std / alloc for rustc | 369 | // Add dependencies on the core / std / alloc for rustc |
402 | for (name, krate) in public_deps.iter() { | 370 | for (name, krate) in public_deps.iter() { |
403 | if let Err(_) = | 371 | add_dep(&mut crate_graph, crate_id, name.clone(), *krate); |
404 | crate_graph.add_dep(crate_id, name.clone(), *krate) | ||
405 | { | ||
406 | log::error!( | ||
407 | "cyclic dependency on {} for {}", | ||
408 | name, | ||
409 | &cargo[pkg].name | ||
410 | ) | ||
411 | } | ||
412 | } | 372 | } |
413 | rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); | 373 | rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); |
414 | } | 374 | } |
@@ -421,13 +381,7 @@ impl ProjectWorkspace { | |||
421 | let name = CrateName::new(&dep.name).unwrap(); | 381 | let name = CrateName::new(&dep.name).unwrap(); |
422 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { | 382 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { |
423 | for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() { | 383 | for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() { |
424 | if let Err(_) = crate_graph.add_dep(from, name.clone(), to) { | 384 | add_dep(&mut crate_graph, from, name.clone(), to); |
425 | log::error!( | ||
426 | "cyclic dependency {} -> {}", | ||
427 | &rustc_workspace[pkg].name, | ||
428 | &rustc_workspace[dep.pkg].name | ||
429 | ) | ||
430 | } | ||
431 | } | 385 | } |
432 | } | 386 | } |
433 | } | 387 | } |
@@ -443,13 +397,7 @@ impl ProjectWorkspace { | |||
443 | continue; | 397 | continue; |
444 | } | 398 | } |
445 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 399 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { |
446 | if let Err(_) = crate_graph.add_dep(from, name.clone(), to) { | 400 | add_dep(&mut crate_graph, from, name.clone(), to); |
447 | log::error!( | ||
448 | "cyclic dependency {} -> {}", | ||
449 | &cargo[pkg].name, | ||
450 | &rustc_workspace[dep].name | ||
451 | ) | ||
452 | } | ||
453 | } | 401 | } |
454 | } | 402 | } |
455 | } | 403 | } |
@@ -520,19 +468,18 @@ fn sysroot_to_crate_graph( | |||
520 | ) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) { | 468 | ) -> (Vec<(CrateName, CrateId)>, Option<CrateId>) { |
521 | let mut cfg_options = CfgOptions::default(); | 469 | let mut cfg_options = CfgOptions::default(); |
522 | cfg_options.extend(get_rustc_cfg_options(target)); | 470 | cfg_options.extend(get_rustc_cfg_options(target)); |
523 | let sysroot_crates: FxHashMap<_, _> = sysroot | 471 | let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = sysroot |
524 | .crates() | 472 | .crates() |
525 | .filter_map(|krate| { | 473 | .filter_map(|krate| { |
526 | let file_id = load(&sysroot[krate].root)?; | 474 | let file_id = load(&sysroot[krate].root)?; |
527 | 475 | ||
528 | let env = Env::default(); | 476 | let env = Env::default(); |
529 | let proc_macro = vec![]; | 477 | let proc_macro = vec![]; |
530 | let name = CrateName::new(&sysroot[krate].name) | 478 | let display_name = CrateDisplayName::from_canonical_name(sysroot[krate].name.clone()); |
531 | .expect("Sysroot crates' names do not contain dashes"); | ||
532 | let crate_id = crate_graph.add_crate_root( | 479 | let crate_id = crate_graph.add_crate_root( |
533 | file_id, | 480 | file_id, |
534 | Edition::Edition2018, | 481 | Edition::Edition2018, |
535 | Some(name.into()), | 482 | Some(display_name), |
536 | cfg_options.clone(), | 483 | cfg_options.clone(), |
537 | env, | 484 | env, |
538 | proc_macro, | 485 | proc_macro, |
@@ -545,9 +492,7 @@ fn sysroot_to_crate_graph( | |||
545 | for &to in sysroot[from].deps.iter() { | 492 | for &to in sysroot[from].deps.iter() { |
546 | let name = CrateName::new(&sysroot[to].name).unwrap(); | 493 | let name = CrateName::new(&sysroot[to].name).unwrap(); |
547 | if let (Some(&from), Some(&to)) = (sysroot_crates.get(&from), sysroot_crates.get(&to)) { | 494 | if let (Some(&from), Some(&to)) = (sysroot_crates.get(&from), sysroot_crates.get(&to)) { |
548 | if let Err(_) = crate_graph.add_dep(from, name, to) { | 495 | add_dep(crate_graph, from, name, to); |
549 | log::error!("cyclic dependency between sysroot crates") | ||
550 | } | ||
551 | } | 496 | } |
552 | } | 497 | } |
553 | } | 498 | } |
@@ -588,3 +533,9 @@ fn get_rustc_cfg_options(target: Option<&str>) -> Vec<CfgFlag> { | |||
588 | 533 | ||
589 | res | 534 | res |
590 | } | 535 | } |
536 | |||
537 | fn add_dep(graph: &mut CrateGraph, from: CrateId, name: CrateName, to: CrateId) { | ||
538 | if let Err(err) = graph.add_dep(from, name, to) { | ||
539 | log::error!("{}", err) | ||
540 | } | ||
541 | } | ||