diff options
Diffstat (limited to 'crates/project_model/src/workspace.rs')
-rw-r--r-- | crates/project_model/src/workspace.rs | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 761fbb3ab..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; |
@@ -407,23 +408,25 @@ fn cargo_to_crate_graph( | |||
407 | } | 408 | } |
408 | } | 409 | } |
409 | 410 | ||
410 | 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)); |
411 | } | 412 | } |
412 | } | 413 | } |
413 | 414 | ||
414 | // 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 |
415 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 416 | for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() { |
416 | if let Some((to, name)) = lib_tgt.clone() { | 417 | if let Some((to, name)) = lib_tgt.clone() { |
417 | if to != from { | 418 | if to != *from && *kind != TargetKind::BuildScript { |
419 | // (build script can not depend on its library target) | ||
420 | |||
418 | // For root projects with dashes in their name, | 421 | // For root projects with dashes in their name, |
419 | // cargo metadata does not do any normalization, | 422 | // cargo metadata does not do any normalization, |
420 | // so we do it ourselves currently | 423 | // so we do it ourselves currently |
421 | let name = CrateName::normalize_dashes(&name); | 424 | let name = CrateName::normalize_dashes(&name); |
422 | add_dep(&mut crate_graph, from, name, to); | 425 | add_dep(&mut crate_graph, *from, name, to); |
423 | } | 426 | } |
424 | } | 427 | } |
425 | for (name, krate) in public_deps.iter() { | 428 | for (name, krate) in public_deps.iter() { |
426 | add_dep(&mut crate_graph, from, name.clone(), *krate); | 429 | add_dep(&mut crate_graph, *from, name.clone(), *krate); |
427 | } | 430 | } |
428 | } | 431 | } |
429 | } | 432 | } |
@@ -434,8 +437,17 @@ fn cargo_to_crate_graph( | |||
434 | for dep in cargo[pkg].dependencies.iter() { | 437 | for dep in cargo[pkg].dependencies.iter() { |
435 | let name = CrateName::new(&dep.name).unwrap(); | 438 | let name = CrateName::new(&dep.name).unwrap(); |
436 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { | 439 | if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) { |
437 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 440 | for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() { |
438 | 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) | ||
439 | } | 451 | } |
440 | } | 452 | } |
441 | } | 453 | } |
@@ -472,7 +484,7 @@ fn handle_rustc_crates( | |||
472 | 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>, |
473 | public_deps: &[(CrateName, CrateId)], | 485 | public_deps: &[(CrateName, CrateId)], |
474 | cargo: &CargoWorkspace, | 486 | cargo: &CargoWorkspace, |
475 | pkg_crates: &FxHashMap<la_arena::Idx<crate::PackageData>, Vec<CrateId>>, | 487 | pkg_crates: &FxHashMap<la_arena::Idx<crate::PackageData>, Vec<(CrateId, TargetKind)>>, |
476 | ) { | 488 | ) { |
477 | let mut rustc_pkg_crates = FxHashMap::default(); | 489 | let mut rustc_pkg_crates = FxHashMap::default(); |
478 | // 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 |
@@ -541,13 +553,13 @@ fn handle_rustc_crates( | |||
541 | if !package.metadata.rustc_private { | 553 | if !package.metadata.rustc_private { |
542 | continue; | 554 | continue; |
543 | } | 555 | } |
544 | for &from in pkg_crates.get(&pkg).into_iter().flatten() { | 556 | for (from, _) in pkg_crates.get(&pkg).into_iter().flatten() { |
545 | // Avoid creating duplicate dependencies | 557 | // Avoid creating duplicate dependencies |
546 | // 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 |
547 | // `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` |
548 | // instead of the one from `crates.io` | 560 | // instead of the one from `crates.io` |
549 | if !crate_graph[from].dependencies.iter().any(|d| d.name == name) { | 561 | if !crate_graph[*from].dependencies.iter().any(|d| d.name == name) { |
550 | add_dep(crate_graph, from, name.clone(), to); | 562 | add_dep(crate_graph, *from, name.clone(), to); |
551 | } | 563 | } |
552 | } | 564 | } |
553 | } | 565 | } |