@@ -6,6 +6,7 @@ use std::{collections::VecDeque, fmt, fs, path::Path, process::Command};
6
6
7
7
use anyhow:: { Context , Result } ;
8
8
use base_db:: { CrateDisplayName , CrateGraph , CrateId , CrateName , Edition , Env , FileId , ProcMacro } ;
9
+ use cargo_workspace:: DepKind ;
9
10
use cfg:: CfgOptions ;
10
11
use paths:: { AbsPath , AbsPathBuf } ;
11
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
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
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
421
// For root projects with dashes in their name,
419
422
// cargo metadata does not do any normalization,
420
423
// so we do it ourselves currently
421
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
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
437
for dep in cargo[ pkg] . dependencies . iter ( ) {
435
438
let name = CrateName :: new ( & dep. name ) . unwrap ( ) ;
436
439
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)
439
451
}
440
452
}
441
453
}
@@ -472,7 +484,7 @@ fn handle_rustc_crates(
472
484
pkg_to_lib_crate : & mut FxHashMap < la_arena:: Idx < crate :: PackageData > , CrateId > ,
473
485
public_deps : & [ ( CrateName , CrateId ) ] ,
474
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
489
let mut rustc_pkg_crates = FxHashMap :: default ( ) ;
478
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
553
if !package. metadata . rustc_private {
542
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
557
// Avoid creating duplicate dependencies
546
558
// This avoids the situation where `from` depends on e.g. `arrayvec`, but
547
559
// `rust_analyzer` thinks that it should use the one from the `rustcSource`
548
560
// 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) ;
551
563
}
552
564
}
553
565
}
0 commit comments