diff options
Diffstat (limited to 'crates/project_model/src/workspace.rs')
-rw-r--r-- | crates/project_model/src/workspace.rs | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 84c702fdf..607e62ea5 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs | |||
@@ -6,6 +6,7 @@ use std::{collections::VecDeque, fmt, fs, path::Path, process::Command}; | |||
6 | 6 | ||
7 | use anyhow::{Context, Result}; | 7 | use anyhow::{Context, Result}; |
8 | use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; | 8 | use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro}; |
9 | use cargo_workspace::DepKind; | ||
9 | use cfg::CfgOptions; | 10 | use cfg::CfgOptions; |
10 | use paths::{AbsPath, AbsPathBuf}; | 11 | use paths::{AbsPath, AbsPathBuf}; |
11 | use proc_macro_api::ProcMacroClient; | 12 | use proc_macro_api::ProcMacroClient; |
@@ -390,6 +391,7 @@ fn cargo_to_crate_graph( | |||
390 | &cfg_options, | 391 | &cfg_options, |
391 | proc_macro_loader, | 392 | proc_macro_loader, |
392 | file_id, | 393 | file_id, |
394 | &cargo[tgt].name, | ||
393 | ); | 395 | ); |
394 | if cargo[tgt].kind == TargetKind::Lib { | 396 | if cargo[tgt].kind == TargetKind::Lib { |
395 | lib_tgt = Some((crate_id, cargo[tgt].name.clone())); | 397 | lib_tgt = Some((crate_id, cargo[tgt].name.clone())); |
@@ -406,23 +408,25 @@ fn cargo_to_crate_graph( | |||
406 | } | 408 | } |
407 | } | 409 | } |
408 | 410 | ||
409 | pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); | 411 | pkg_crates.entry(pkg).or_insert_with(Vec::new).push((crate_id, cargo[tgt].kind)); |
410 | } | 412 | } |
411 | } | 413 | } |
412 | 414 | ||
413 | // Set deps to the core, std and to the lib target of the current package | 415 | // Set deps to the core, std and to the lib target of the current package |
414 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 416 | for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() { |
415 | if let Some((to, name)) = lib_tgt.clone() { | 417 | if let Some((to, name)) = lib_tgt.clone() { |
416 | if to != from { | 418 | if to != *from && *kind != TargetKind::BuildScript { |
419 | // (build script can not depend on its library target) | ||
420 | |||
417 | // For root projects with dashes in their name, | 421 | // For root projects with dashes in their name, |
418 | // cargo metadata does not do any normalization, | 422 | // cargo metadata does not do any normalization, |
419 | // so we do it ourselves currently | 423 | // so we do it ourselves currently |
420 | let name = CrateName::normalize_dashes(&name); | 424 | let name = CrateName::normalize_dashes(&name); |
421 | add_dep(&mut crate_graph, from, name, to); | 425 | add_dep(&mut crate_graph, *from, name, to); |
422 | } | 426 | } |
423 | } | 427 | } |
424 | for (name, krate) in public_deps.iter() { | 428 | for (name, krate) in public_deps.iter() { |
425 | add_dep(&mut crate_graph, from, name.clone(), *krate); | 429 | add_dep(&mut crate_graph, *from, name.clone(), *krate); |
426 | } | 430 | } |
427 | } | 431 | } |
428 | } | 432 | } |
@@ -433,8 +437,17 @@ fn cargo_to_crate_graph( | |||
433 | for dep in cargo[pkg].dependencies.iter() { | 437 | for dep in cargo[pkg].dependencies.iter() { |
434 | let name = CrateName::new(&dep.name).unwrap(); | 438 | let name = CrateName::new(&dep.name).unwrap(); |
435 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { | 439 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { |
436 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 440 | for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() { |
437 | add_dep(&mut crate_graph, from, name.clone(), to) | 441 | if dep.kind == DepKind::Build && *kind != TargetKind::BuildScript { |
442 | // Only build scripts may depend on build dependencies. | ||
443 | continue; | ||
444 | } | ||
445 | if dep.kind != DepKind::Build && *kind == TargetKind::BuildScript { | ||
446 | // Build scripts may only depend on build dependencies. | ||
447 | continue; | ||
448 | } | ||
449 | |||
450 | add_dep(&mut crate_graph, *from, name.clone(), to) | ||
438 | } | 451 | } |
439 | } | 452 | } |
440 | } | 453 | } |
@@ -471,7 +484,7 @@ fn handle_rustc_crates( | |||
471 | pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>, | 484 | pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>, |
472 | public_deps: &[(CrateName, CrateId)], | 485 | public_deps: &[(CrateName, CrateId)], |
473 | cargo: &CargoWorkspace, | 486 | cargo: &CargoWorkspace, |
474 | pkg_crates: &FxHashMap<la_arena::Idx<crate::PackageData>, Vec<CrateId>>, | 487 | pkg_crates: &FxHashMap<la_arena::Idx<crate::PackageData>, Vec<(CrateId, TargetKind)>>, |
475 | ) { | 488 | ) { |
476 | let mut rustc_pkg_crates = FxHashMap::default(); | 489 | let mut rustc_pkg_crates = FxHashMap::default(); |
477 | // The root package of the rustc-dev component is rustc_driver, so we match that | 490 | // The root package of the rustc-dev component is rustc_driver, so we match that |
@@ -505,6 +518,7 @@ fn handle_rustc_crates( | |||
505 | &cfg_options, | 518 | &cfg_options, |
506 | proc_macro_loader, | 519 | proc_macro_loader, |
507 | file_id, | 520 | file_id, |
521 | &rustc_workspace[tgt].name, | ||
508 | ); | 522 | ); |
509 | pkg_to_lib_crate.insert(pkg, crate_id); | 523 | pkg_to_lib_crate.insert(pkg, crate_id); |
510 | // Add dependencies on core / std / alloc for this crate | 524 | // Add dependencies on core / std / alloc for this crate |
@@ -539,13 +553,13 @@ fn handle_rustc_crates( | |||
539 | if !package.metadata.rustc_private { | 553 | if !package.metadata.rustc_private { |
540 | continue; | 554 | continue; |
541 | } | 555 | } |
542 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 556 | for (from, _) in pkg_crates.get(&pkg).into_iter().flatten() { |
543 | // Avoid creating duplicate dependencies | 557 | // Avoid creating duplicate dependencies |
544 | // This avoids the situation where `from` depends on e.g. `arrayvec`, but | 558 | // This avoids the situation where `from` depends on e.g. `arrayvec`, but |
545 | // `rust_analyzer` thinks that it should use the one from the `rustcSource` | 559 | // `rust_analyzer` thinks that it should use the one from the `rustcSource` |
546 | // instead of the one from `crates.io` | 560 | // instead of the one from `crates.io` |
547 | if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { | 561 | if !crate_graph[*from].dependencies.iter().any(|d| d.name == name) { |
548 | add_dep(crate_graph, from, name.clone(), to); | 562 | add_dep(crate_graph, *from, name.clone(), to); |
549 | } | 563 | } |
550 | } | 564 | } |
551 | } | 565 | } |
@@ -560,6 +574,7 @@ fn add_target_crate_root( | |||
560 | cfg_options: &CfgOptions, | 574 | cfg_options: &CfgOptions, |
561 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, | 575 | proc_macro_loader: &dyn Fn(&Path) -> Vec<ProcMacro>, |
562 | file_id: FileId, | 576 | file_id: FileId, |
577 | cargo_name: &str, | ||
563 | ) -> CrateId { | 578 | ) -> CrateId { |
564 | let edition = pkg.edition; | 579 | let edition = pkg.edition; |
565 | let cfg_options = { | 580 | let cfg_options = { |
@@ -586,7 +601,7 @@ fn add_target_crate_root( | |||
586 | .map(|it| proc_macro_loader(&it)) | 601 | .map(|it| proc_macro_loader(&it)) |
587 | .unwrap_or_default(); | 602 | .unwrap_or_default(); |
588 | 603 | ||
589 | let display_name = CrateDisplayName::from_canonical_name(pkg.name.clone()); | 604 | let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_string()); |
590 | let crate_id = crate_graph.add_crate_root( | 605 | let crate_id = crate_graph.add_crate_root( |
591 | file_id, | 606 | file_id, |
592 | edition, | 607 | edition, |