aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-11-17 10:53:12 +0000
committerGitHub <[email protected]>2020-11-17 10:53:12 +0000
commit10e3a9879c8714320f9a0729d647da7877f0a753 (patch)
treeb480f5f51f9bb14e689c5b61fdfab3d0d013956c
parentc7c4e9180b3d36586d85fb11361321a27dac5193 (diff)
parent0dc1742187d36b559d5d62ada3989901fdbd074c (diff)
Merge #6571
6571: Cleanup project model r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/base_db/src/input.rs20
-rw-r--r--crates/project_model/src/sysroot.rs2
-rw-r--r--crates/project_model/src/workspace.rs161
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 {
421impl std::error::Error for ParseEditionError {} 424impl std::error::Error for ParseEditionError {}
422 425
423#[derive(Debug)] 426#[derive(Debug)]
424pub struct CyclicDependenciesError; 427pub struct CyclicDependenciesError {
428 from: (CrateId, Option<CrateDisplayName>),
429 to: (CrateId, Option<CrateDisplayName>),
430}
431
432impl 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)]
427mod tests { 443mod 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;
12use rustc_hash::{FxHashMap, FxHashSet}; 12use rustc_hash::{FxHashMap, FxHashSet};
13 13
14use crate::{ 14use 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
537fn 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}