diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-12 14:22:23 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-12 14:22:23 +0100 |
commit | a5b55828365b602f0ed117c9f1cc2a9eddd42512 (patch) | |
tree | 92c544276f4556e02c434321f2e0407d54d68a02 /crates | |
parent | 9a431c26f4528e2649de0ca171a38c93e473c94e (diff) | |
parent | a272cdfecdbbd95725d66b2452da3d379ef35d76 (diff) |
Merge #8812
8812: fix: fix dependencies of build scripts r=jonas-schievink a=jonas-schievink
Previously, we added a dependency for all targets in a package to the package's library target. This is correct for most targets, except build scripts, which run before the library crate is built. This PR removes the incorrect dependency on the library target.
We also used to treat all dependencies the same, which led to build scripts being able to use regular dependencies as well as dev-dependencies. This is also fixed by this PR, and build scripts only depend on build-dependencies.
Incorrect dependency graph:
![screenshot-2021-05-11-23:35:01](https://user-images.githubusercontent.com/1786438/117975228-c2066a80-b32e-11eb-8f01-1e3ea904a608.png)
Fixed graph after this PR:
![screenshot-2021-05-12-14:29:31](https://user-images.githubusercontent.com/1786438/117975253-c9c60f00-b32e-11eb-8f6c-9e42d4e32468.png)
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/project_model/src/cargo_workspace.rs | 34 | ||||
-rw-r--r-- | crates/project_model/src/workspace.rs | 34 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cargo_target_spec.rs | 2 |
3 files changed, 57 insertions, 13 deletions
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index b18699b77..4a4996cf4 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs | |||
@@ -119,6 +119,32 @@ pub struct RustAnalyzerPackageMetaData { | |||
119 | pub struct PackageDependency { | 119 | pub struct PackageDependency { |
120 | pub pkg: Package, | 120 | pub pkg: Package, |
121 | pub name: String, | 121 | pub name: String, |
122 | pub kind: DepKind, | ||
123 | } | ||
124 | |||
125 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
126 | pub enum DepKind { | ||
127 | /// Available to the library, binary, and dev targets in the package (but not the build script). | ||
128 | Normal, | ||
129 | /// Available only to test and bench targets (and the library target, when built with `cfg(test)`). | ||
130 | Dev, | ||
131 | /// Available only to the build script target. | ||
132 | Build, | ||
133 | } | ||
134 | |||
135 | impl DepKind { | ||
136 | fn new(list: &[cargo_metadata::DepKindInfo]) -> Self { | ||
137 | for info in list { | ||
138 | match info.kind { | ||
139 | cargo_metadata::DependencyKind::Normal => return Self::Normal, | ||
140 | cargo_metadata::DependencyKind::Development => return Self::Dev, | ||
141 | cargo_metadata::DependencyKind::Build => return Self::Build, | ||
142 | cargo_metadata::DependencyKind::Unknown => continue, | ||
143 | } | ||
144 | } | ||
145 | |||
146 | Self::Normal | ||
147 | } | ||
122 | } | 148 | } |
123 | 149 | ||
124 | /// Information associated with a package's target | 150 | /// Information associated with a package's target |
@@ -144,6 +170,7 @@ pub enum TargetKind { | |||
144 | Example, | 170 | Example, |
145 | Test, | 171 | Test, |
146 | Bench, | 172 | Bench, |
173 | BuildScript, | ||
147 | Other, | 174 | Other, |
148 | } | 175 | } |
149 | 176 | ||
@@ -155,6 +182,7 @@ impl TargetKind { | |||
155 | "test" => TargetKind::Test, | 182 | "test" => TargetKind::Test, |
156 | "bench" => TargetKind::Bench, | 183 | "bench" => TargetKind::Bench, |
157 | "example" => TargetKind::Example, | 184 | "example" => TargetKind::Example, |
185 | "custom-build" => TargetKind::BuildScript, | ||
158 | "proc-macro" => TargetKind::Lib, | 186 | "proc-macro" => TargetKind::Lib, |
159 | _ if kind.contains("lib") => TargetKind::Lib, | 187 | _ if kind.contains("lib") => TargetKind::Lib, |
160 | _ => continue, | 188 | _ => continue, |
@@ -301,7 +329,11 @@ impl CargoWorkspace { | |||
301 | continue; | 329 | continue; |
302 | } | 330 | } |
303 | }; | 331 | }; |
304 | let dep = PackageDependency { name: dep_node.name, pkg }; | 332 | let dep = PackageDependency { |
333 | name: dep_node.name, | ||
334 | pkg, | ||
335 | kind: DepKind::new(&dep_node.dep_kinds), | ||
336 | }; | ||
305 | packages[source].dependencies.push(dep); | 337 | packages[source].dependencies.push(dep); |
306 | } | 338 | } |
307 | packages[source].active_features.extend(node.features); | 339 | packages[source].active_features.extend(node.features); |
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 | } |
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs index 909c21532..f4cd43448 100644 --- a/crates/rust-analyzer/src/cargo_target_spec.rs +++ b/crates/rust-analyzer/src/cargo_target_spec.rs | |||
@@ -159,7 +159,7 @@ impl CargoTargetSpec { | |||
159 | TargetKind::Lib => { | 159 | TargetKind::Lib => { |
160 | buf.push("--lib".to_string()); | 160 | buf.push("--lib".to_string()); |
161 | } | 161 | } |
162 | TargetKind::Other => (), | 162 | TargetKind::Other | TargetKind::BuildScript => (), |
163 | } | 163 | } |
164 | } | 164 | } |
165 | } | 165 | } |