aboutsummaryrefslogtreecommitdiff
path: root/crates/project_model
diff options
context:
space:
mode:
Diffstat (limited to 'crates/project_model')
-rw-r--r--crates/project_model/src/cargo_workspace.rs2
-rw-r--r--crates/project_model/src/workspace.rs138
2 files changed, 70 insertions, 70 deletions
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs
index beda2f61f..bc6e20341 100644
--- a/crates/project_model/src/cargo_workspace.rs
+++ b/crates/project_model/src/cargo_workspace.rs
@@ -112,7 +112,7 @@ pub struct PackageData {
112 112
113#[derive(Deserialize, Default, Debug, Clone, Eq, PartialEq)] 113#[derive(Deserialize, Default, Debug, Clone, Eq, PartialEq)]
114pub struct RustAnalyzerPackageMetaData { 114pub struct RustAnalyzerPackageMetaData {
115 pub rustc_private: Option<bool>, 115 pub rustc_private: bool,
116} 116}
117 117
118#[derive(Debug, Clone, Eq, PartialEq)] 118#[derive(Debug, Clone, Eq, PartialEq)]
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index cacf462cf..b969420cf 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -376,9 +376,10 @@ fn cargo_to_crate_graph(
376 cfg_options.insert_atom("debug_assertions".into()); 376 cfg_options.insert_atom("debug_assertions".into());
377 377
378 let mut pkg_crates = FxHashMap::default(); 378 let mut pkg_crates = FxHashMap::default();
379 379 let mut has_private = false;
380 // Next, create crates for each package, target pair 380 // Next, create crates for each package, target pair
381 for pkg in cargo.packages() { 381 for pkg in cargo.packages() {
382 has_private |= cargo[pkg].metadata.rustc_private;
382 let mut lib_tgt = None; 383 let mut lib_tgt = None;
383 for &tgt in cargo[pkg].targets.iter() { 384 for &tgt in cargo[pkg].targets.iter() {
384 if let Some(file_id) = load(&cargo[tgt].root) { 385 if let Some(file_id) = load(&cargo[tgt].root) {
@@ -441,89 +442,88 @@ fn cargo_to_crate_graph(
441 442
442 let mut rustc_pkg_crates = FxHashMap::default(); 443 let mut rustc_pkg_crates = FxHashMap::default();
443 444
444 // If the user provided a path to rustc sources, we add all the rustc_private crates 445 if has_private {
445 // and create dependencies on them for the crates which opt-in to that 446 // If the user provided a path to rustc sources, we add all the rustc_private crates
446 if let Some(rustc_workspace) = rustc { 447 // and create dependencies on them for the crates which opt-in to that
447 // rustc-dev crates start from 'rustc_driver' 448 if let Some(rustc_workspace) = rustc {
448 // Therefore, we collect all crates which are transitive dependencies of rustc_driver 449 // rustc-dev crates start from 'rustc_driver'
449 if let Some(root_pkg) = rustc_workspace 450 // We want to collect all crates which are transitive dependencies of rustc_driver
450 .packages() 451 if let Some(root_pkg) = rustc_workspace
451 .find(|package| rustc_workspace[*package].name == "rustc_driver") 452 .packages()
452 { 453 .find(|package| rustc_workspace[*package].name == "rustc_driver")
453 let mut queue = VecDeque::new(); 454 {
454 queue.push_back(root_pkg); 455 let mut queue = VecDeque::new();
455 while let Some(pkg) = queue.pop_front() { 456 queue.push_back(root_pkg);
456 if rustc_pkg_crates.contains_key(&pkg) { 457 while let Some(pkg) = queue.pop_front() {
457 continue; 458 // Don't duplicate packages
458 } 459 if rustc_pkg_crates.contains_key(&pkg) {
459 for dep in &rustc_workspace[pkg].dependencies {
460 queue.push_back(dep.pkg);
461 }
462 for &tgt in rustc_workspace[pkg].targets.iter() {
463 if rustc_workspace[tgt].kind != TargetKind::Lib {
464 continue; 460 continue;
465 } 461 }
466 if let Some(file_id) = load(&rustc_workspace[tgt].root) { 462 for dep in &rustc_workspace[pkg].dependencies {
467 let crate_id = add_target_crate_root( 463 queue.push_back(dep.pkg);
468 &mut crate_graph, 464 }
469 &rustc_workspace[pkg], 465 for &tgt in rustc_workspace[pkg].targets.iter() {
470 rustc_build_data_map.and_then(|it| it.get(&rustc_workspace[pkg].id)), 466 if rustc_workspace[tgt].kind != TargetKind::Lib {
471 &cfg_options, 467 continue;
472 proc_macro_loader, 468 }
473 file_id, 469 if let Some(file_id) = load(&rustc_workspace[tgt].root) {
474 ); 470 let crate_id = add_target_crate_root(
475 pkg_to_lib_crate.insert(pkg, crate_id); 471 &mut crate_graph,
476 // Add dependencies on the core / std / alloc for rustc 472 &rustc_workspace[pkg],
477 for (name, krate) in public_deps.iter() { 473 rustc_build_data_map
478 add_dep(&mut crate_graph, crate_id, name.clone(), *krate); 474 .and_then(|it| it.get(&rustc_workspace[pkg].id)),
475 &cfg_options,
476 proc_macro_loader,
477 file_id,
478 );
479 pkg_to_lib_crate.insert(pkg, crate_id);
480 // Add dependencies on the core / std / alloc for rustc
481 for (name, krate) in public_deps.iter() {
482 add_dep(&mut crate_graph, crate_id, name.clone(), *krate);
483 }
484 rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
479 } 485 }
480 rustc_pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id);
481 } 486 }
482 } 487 }
483 } 488 }
484 } 489 // Now add a dep edge from all targets of upstream to the lib
485 // Now add a dep edge from all targets of upstream to the lib 490 // target of downstream.
486 // target of downstream. 491 for pkg in rustc_pkg_crates.keys().copied() {
487 for pkg in rustc_pkg_crates.keys().copied() { 492 for dep in rustc_workspace[pkg].dependencies.iter() {
488 for dep in rustc_workspace[pkg].dependencies.iter() { 493 let name = CrateName::new(&dep.name).unwrap();
489 let name = CrateName::new(&dep.name).unwrap(); 494 if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
490 if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { 495 for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() {
491 for &from in rustc_pkg_crates.get(&pkg).into_iter().flatten() { 496 add_dep(&mut crate_graph, from, name.clone(), to);
492 add_dep(&mut crate_graph, from, name.clone(), to); 497 }
493 } 498 }
494 } 499 }
495 } 500 }
496 }
497 501
498 // Add dependencies for all crates which opt in to rustc_private libraries 502 // Add dependencies for all crates which opt in to rustc_private libraries
499 for dep in rustc_workspace.packages() { 503 for dep in rustc_workspace.packages() {
500 let name = CrateName::normalize_dashes(&rustc_workspace[dep].name); 504 let name = CrateName::normalize_dashes(&rustc_workspace[dep].name);
501 505
502 if let Some(&to) = pkg_to_lib_crate.get(&dep) { 506 if let Some(&to) = pkg_to_lib_crate.get(&dep) {
503 for pkg in cargo.packages() { 507 for pkg in cargo.packages() {
504 let package = &cargo[pkg]; 508 let package = &cargo[pkg];
505 if matches!( 509 if !package.metadata.rustc_private {
506 (package.is_member, package.metadata.rustc_private), 510 continue;
507 (true, Some(false)) | (false, Some(false)) | (false, None) 511 }
508 ) { 512 for &from in pkg_crates.get(&pkg).into_iter().flatten() {
509 continue; 513 // Avoid creating duplicate dependencies
510 } 514 if !crate_graph[from].dependencies.iter().any(|d| d.name == name) {
511 for &from in pkg_crates.get(&pkg).into_iter().flatten() { 515 add_dep(&mut crate_graph, from, name.clone(), to);
512 // Avoid creating duplicate dependencies 516 } else {
513 if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { 517 eprintln!(
514 add_dep(&mut crate_graph, from, name.clone(), to); 518 "Skipped {} for {:?}",
515 } else { 519 &name, &crate_graph[from].display_name
516 eprintln!( 520 );
517 "Skipped {} for {:?}", 521 }
518 &name, &crate_graph[from].display_name
519 );
520 } 522 }
521 } 523 }
522 } 524 }
523 } 525 }
524 } 526 }
525 } else {
526 eprintln!("No cargo workspace");
527 } 527 }
528 crate_graph 528 crate_graph
529} 529}