Skip to content

Commit a272cdf

Browse files
Fix build script dependencies
1 parent 9a431c2 commit a272cdf

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

crates/project_model/src/cargo_workspace.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,32 @@ pub struct RustAnalyzerPackageMetaData {
119119
pub struct PackageDependency {
120120
pub pkg: Package,
121121
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+
}
122148
}
123149

124150
/// Information associated with a package's target
@@ -144,6 +170,7 @@ pub enum TargetKind {
144170
Example,
145171
Test,
146172
Bench,
173+
BuildScript,
147174
Other,
148175
}
149176

@@ -155,6 +182,7 @@ impl TargetKind {
155182
"test" => TargetKind::Test,
156183
"bench" => TargetKind::Bench,
157184
"example" => TargetKind::Example,
185+
"custom-build" => TargetKind::BuildScript,
158186
"proc-macro" => TargetKind::Lib,
159187
_ if kind.contains("lib") => TargetKind::Lib,
160188
_ => continue,
@@ -301,7 +329,11 @@ impl CargoWorkspace {
301329
continue;
302330
}
303331
};
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+
};
305337
packages[source].dependencies.push(dep);
306338
}
307339
packages[source].active_features.extend(node.features);

crates/project_model/src/workspace.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::{collections::VecDeque, fmt, fs, path::Path, process::Command};
66

77
use anyhow::{Context, Result};
88
use base_db::{CrateDisplayName, CrateGraph, CrateId, CrateName, Edition, Env, FileId, ProcMacro};
9+
use cargo_workspace::DepKind;
910
use cfg::CfgOptions;
1011
use paths::{AbsPath, AbsPathBuf};
1112
use proc_macro_api::ProcMacroClient;
@@ -407,23 +408,25 @@ fn cargo_to_crate_graph(
407408
}
408409
}
409410

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));
411412
}
412413
}
413414

414415
// 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() {
416417
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+
418421
// For root projects with dashes in their name,
419422
// cargo metadata does not do any normalization,
420423
// so we do it ourselves currently
421424
let name = CrateName::normalize_dashes(&name);
422-
add_dep(&mut crate_graph, from, name, to);
425+
add_dep(&mut crate_graph, *from, name, to);
423426
}
424427
}
425428
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);
427430
}
428431
}
429432
}
@@ -434,8 +437,17 @@ fn cargo_to_crate_graph(
434437
for dep in cargo[pkg].dependencies.iter() {
435438
let name = CrateName::new(&dep.name).unwrap();
436439
if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
437-
for &from in pkg_crates.get(&pkg).into_iter().flatten() {
438-
add_dep(&mut crate_graph, from, name.clone(), to)
440+
for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
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)
439451
}
440452
}
441453
}
@@ -472,7 +484,7 @@ fn handle_rustc_crates(
472484
pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>,
473485
public_deps: &[(CrateName, CrateId)],
474486
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)>>,
476488
) {
477489
let mut rustc_pkg_crates = FxHashMap::default();
478490
// The root package of the rustc-dev component is rustc_driver, so we match that
@@ -541,13 +553,13 @@ fn handle_rustc_crates(
541553
if !package.metadata.rustc_private {
542554
continue;
543555
}
544-
for &from in pkg_crates.get(&pkg).into_iter().flatten() {
556+
for (from, _) in pkg_crates.get(&pkg).into_iter().flatten() {
545557
// Avoid creating duplicate dependencies
546558
// This avoids the situation where `from` depends on e.g. `arrayvec`, but
547559
// `rust_analyzer` thinks that it should use the one from the `rustcSource`
548560
// instead of the one from `crates.io`
549-
if !crate_graph[from].dependencies.iter().any(|d| d.name == name) {
550-
add_dep(crate_graph, from, name.clone(), to);
561+
if !crate_graph[*from].dependencies.iter().any(|d| d.name == name) {
562+
add_dep(crate_graph, *from, name.clone(), to);
551563
}
552564
}
553565
}

crates/rust-analyzer/src/cargo_target_spec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ impl CargoTargetSpec {
159159
TargetKind::Lib => {
160160
buf.push("--lib".to_string());
161161
}
162-
TargetKind::Other => (),
162+
TargetKind::Other | TargetKind::BuildScript => (),
163163
}
164164
}
165165
}

0 commit comments

Comments
 (0)