From 62ce8c4b578b938e93071ca3e0a35564077fdaf9 Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Thu, 16 Feb 2023 19:30:35 +1100 Subject: [PATCH 1/5] Only add dev dependencies to the dependency list of dev targets Fixes #9574 Fixes #11410 `rust-analyzer` already counts all of the different targets of a crate as different crates, so it was pretty easy to just exclude dev dependencies from the dependency lists of the targets other than test, dev and bench when ingesting `cargo metadata`'s output. A similar thing is already done for build dependencies. It's possible there might be something I'm missing here, since this is quite a long-standing issue which I expected to be much more complicated to solve; but, this seems to work. The circular dependency errors that `rust-analyzer` used to throw on `wasm-bindgen` went away after switching to this patched version. --- crates/project-model/src/workspace.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 2a11f1e8eb82..7cc12ea9f3ab 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -915,6 +915,16 @@ fn cargo_to_crate_graph( continue; } + if dep.kind == DepKind::Dev + && !matches!( + kind, + TargetKind::Test | TargetKind::Example | TargetKind::Bench + ) + { + // Only tests, examples and benchmarks may depend on dev dependencies. + continue; + } + add_dep(&mut crate_graph, from, name.clone(), to) } } From a0e7b1601ebf76c18ca7218a0233916a7dd03aba Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Sat, 18 Feb 2023 09:15:44 +1100 Subject: [PATCH 2/5] Enable dev dependencies for bin and lib crates in test mode I also had to change the logic for whether they get put into test mode or not: * Bin crates now only get put into test mode if they're a part of the current workspace, because otherwise dev dependencies don't work * this didn't actually change anything because bin crates outside the current workspace are already ignored but idk it's better to make it explicit? * The version of a lib crate with test mode enabled is now separate from the normal version of the lib crate, since it's allowed to depend on the normal version as a dev dependency. (as suggested in https://github.com/rust-lang/rust-analyzer/issues/2414#issuecomment-561213070) * The test-mode version of the lib crate is also only created if it's a part of the current workspace. --- crates/project-model/src/workspace.rs | 105 +++++++++++++++++--------- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 7cc12ea9f3ab..35ec83e1ebc8 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -9,7 +9,7 @@ use base_db::{ CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Edition, Env, FileId, LangCrateOrigin, ProcMacroLoadResult, TargetLayoutLoadResult, }; -use cfg::{CfgDiff, CfgOptions}; +use cfg::{CfgDiff, CfgExpr, CfgOptions}; use paths::{AbsPath, AbsPathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; use semver::Version; @@ -820,11 +820,6 @@ fn cargo_to_crate_graph( CfgOverrides::Selective(cfg_overrides) => cfg_overrides.get(&cargo[pkg].name), }; - // Add test cfg for local crates - if cargo[pkg].is_local { - cfg_options.insert_atom("test".into()); - } - if let Some(overrides) = overrides { // FIXME: this is sort of a hack to deal with #![cfg(not(test))] vanishing such as seen // in ed25519_dalek (#7243), and libcore (#9203) (although you only hit that one while @@ -849,34 +844,67 @@ fn cargo_to_crate_graph( } if let Some(file_id) = load(&cargo[tgt].root) { - let crate_id = add_target_crate_root( - &mut crate_graph, - &cargo[pkg], - build_scripts.get_output(pkg), - cfg_options.clone(), - &mut |path| load_proc_macro(&cargo[tgt].name, path), - file_id, - &cargo[tgt].name, - cargo[tgt].is_proc_macro, - target_layout.clone(), - ); - if cargo[tgt].kind == TargetKind::Lib { - lib_tgt = Some((crate_id, cargo[tgt].name.clone())); - pkg_to_lib_crate.insert(pkg, crate_id); - } - // Even crates that don't set proc-macro = true are allowed to depend on proc_macro - // (just none of the APIs work when called outside of a proc macro). - if let Some(proc_macro) = libproc_macro { - add_dep_with_prelude( + let mut add_crate = |cfg_options: &CfgOptions| { + let crate_id = add_target_crate_root( &mut crate_graph, - crate_id, - CrateName::new("proc_macro").unwrap(), - proc_macro, + &cargo[pkg], + build_scripts.get_output(pkg), + cfg_options.clone(), + &mut |path| load_proc_macro(&cargo[tgt].name, path), + file_id, + &cargo[tgt].name, cargo[tgt].is_proc_macro, + target_layout.clone(), ); + // Even crates that don't set proc-macro = true are allowed to depend on proc_macro + // (just none of the APIs work when called outside of a proc macro). + if let Some(proc_macro) = libproc_macro { + add_dep_with_prelude( + &mut crate_graph, + crate_id, + CrateName::new("proc_macro").unwrap(), + proc_macro, + cargo[tgt].is_proc_macro, + ); + } + pkg_crates + .entry(pkg) + .or_insert_with(Vec::new) + .push((crate_id, cargo[tgt].kind)); + crate_id + }; + + let mut cfg_options = cfg_options.clone(); + // Enable cfg(test) for bin crates in the current workspace so that diagnostics + // are provided for tests. + // They have to be in the current workspace because tests are allowed to use dev + // depedencies, which cargo only resolves for crates in the current workspace. + // Lib crates are more complicated because the test version of the crate can + // actually depend on the normal version of the crate, which we handle below. + if cargo[pkg].is_member && cargo[tgt].kind == TargetKind::Bin { + cfg_options.insert_atom("test".into()); } - pkg_crates.entry(pkg).or_insert_with(Vec::new).push((crate_id, cargo[tgt].kind)); + let crate_id = add_crate(&cfg_options); + + if cargo[tgt].kind == TargetKind::Lib { + // Mark this as the lib crate for this package. + lib_tgt = Some((crate_id, cargo[tgt].name.clone())); + pkg_to_lib_crate.insert(pkg, crate_id); + + if cargo[pkg].is_member { + // Create another version of the crate with cfg(test) enabled. + // This, as for bin crates, is so that diagnostics are provided for tests, but + // it needs to be treated as a separate crate because it can actually depend on + // the normal version of the crate when it's specified as a dev dependency. + // + // We only do this if the package is a member of this workspace, because cargo + // doesn't resolve dev-dependencies for packages outside the workspace and so + // any unit tests that use them won't work properly. + cfg_options.insert_atom("test".into()); + add_crate(&cfg_options); + } + } } } @@ -915,13 +943,18 @@ fn cargo_to_crate_graph( continue; } - if dep.kind == DepKind::Dev - && !matches!( - kind, - TargetKind::Test | TargetKind::Example | TargetKind::Bench - ) - { - // Only tests, examples and benchmarks may depend on dev dependencies. + let crate_data = &crate_graph[from]; + let test_cfg = CfgExpr::Atom(cfg::CfgAtom::Flag("test".into())); + // Dev dependencies can be used by tests, examples, and benchmarks, + // as well as bin and lib crates when compiling in test mode. + let dev_deps_enabled = + matches!(kind, TargetKind::Test | TargetKind::Example | TargetKind::Bench) + || (matches!(kind, TargetKind::Bin | TargetKind::Lib) + && crate_data + .cfg_options + .check(&test_cfg) + .expect("cfg(test) was somehow an invalid cfg")); + if dep.kind == DepKind::Dev && !dev_deps_enabled { continue; } From 37f60bfbd7cdbcc52caf7e02a58262151871e0b4 Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Sat, 18 Feb 2023 10:13:34 +1100 Subject: [PATCH 3/5] Update test expectations --- crates/project-model/src/tests.rs | 301 +++++++++++++++++++++++++++--- 1 file changed, 270 insertions(+), 31 deletions(-) diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index 9e9691d11e85..85e03dd71159 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -176,7 +176,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { dependencies: [ Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -199,7 +199,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { 1, ): CrateData { root_file_id: FileId( - 2, + 1, ), edition: Edition2018, version: Some( @@ -216,11 +216,13 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { cfg_options: CfgOptions( [ "debug_assertions", + "test", ], ), potential_cfg_options: CfgOptions( [ "debug_assertions", + "test", ], ), target_layout: Err( @@ -257,7 +259,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -278,6 +280,89 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { }, CrateId( 2, + ): CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2018, + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "test", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "test", + ], + ), + target_layout: Err( + "target_data_layout not loaded", + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$hello-world", + "CARGO_PKG_VERSION": "0.1.0", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "hello_world", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "hello-world", + "CARGO_PKG_VERSION_PATCH": "0", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "1", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [ + Dependency { + crate_id: CrateId( + 0, + ), + name: CrateName( + "hello_world", + ), + prelude: true, + }, + Dependency { + crate_id: CrateId( + 5, + ), + name: CrateName( + "libc", + ), + prelude: true, + }, + ], + proc_macro: Err( + "crate has not (yet) been built", + ), + origin: CratesIo { + repo: None, + name: Some( + "hello-world", + ), + }, + is_proc_macro: false, + }, + CrateId( + 3, ): CrateData { root_file_id: FileId( 3, @@ -338,7 +423,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -358,7 +443,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { is_proc_macro: false, }, CrateId( - 3, + 4, ): CrateData { root_file_id: FileId( 4, @@ -419,7 +504,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -439,7 +524,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { is_proc_macro: false, }, CrateId( - 4, + 5, ): CrateData { root_file_id: FileId( 5, @@ -535,6 +620,78 @@ fn cargo_hello_world_project_model_with_selective_overrides() { arena: { CrateId( 0, + ): CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2018, + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + target_layout: Err( + "target_data_layout not loaded", + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$hello-world", + "CARGO_PKG_VERSION": "0.1.0", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "hello_world", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "hello-world", + "CARGO_PKG_VERSION_PATCH": "0", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "1", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [ + Dependency { + crate_id: CrateId( + 5, + ), + name: CrateName( + "libc", + ), + prelude: true, + }, + ], + proc_macro: Err( + "crate has not (yet) been built", + ), + origin: CratesIo { + repo: None, + name: Some( + "hello-world", + ), + }, + is_proc_macro: false, + }, + CrateId( + 1, ): CrateData { root_file_id: FileId( 1, @@ -588,7 +745,16 @@ fn cargo_hello_world_project_model_with_selective_overrides() { dependencies: [ Dependency { crate_id: CrateId( - 4, + 0, + ), + name: CrateName( + "hello_world", + ), + prelude: true, + }, + Dependency { + crate_id: CrateId( + 5, ), name: CrateName( "libc", @@ -608,7 +774,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { is_proc_macro: false, }, CrateId( - 1, + 2, ): CrateData { root_file_id: FileId( 2, @@ -671,7 +837,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -691,7 +857,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { is_proc_macro: false, }, CrateId( - 2, + 3, ): CrateData { root_file_id: FileId( 3, @@ -711,13 +877,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() { cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), potential_cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), target_layout: Err( @@ -754,7 +918,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -774,7 +938,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { is_proc_macro: false, }, CrateId( - 3, + 4, ): CrateData { root_file_id: FileId( 4, @@ -794,13 +958,11 @@ fn cargo_hello_world_project_model_with_selective_overrides() { cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), potential_cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), target_layout: Err( @@ -837,7 +999,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -857,7 +1019,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() { is_proc_macro: false, }, CrateId( - 4, + 5, ): CrateData { root_file_id: FileId( 5, @@ -944,6 +1106,78 @@ fn cargo_hello_world_project_model() { arena: { CrateId( 0, + ): CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2018, + version: Some( + "0.1.0", + ), + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + target_layout: Err( + "target_data_layout not loaded", + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$hello-world", + "CARGO_PKG_VERSION": "0.1.0", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "hello_world", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "hello-world", + "CARGO_PKG_VERSION_PATCH": "0", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "1", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [ + Dependency { + crate_id: CrateId( + 5, + ), + name: CrateName( + "libc", + ), + prelude: true, + }, + ], + proc_macro: Err( + "crate has not (yet) been built", + ), + origin: CratesIo { + repo: None, + name: Some( + "hello-world", + ), + }, + is_proc_macro: false, + }, + CrateId( + 1, ): CrateData { root_file_id: FileId( 1, @@ -997,7 +1231,16 @@ fn cargo_hello_world_project_model() { dependencies: [ Dependency { crate_id: CrateId( - 4, + 0, + ), + name: CrateName( + "hello_world", + ), + prelude: true, + }, + Dependency { + crate_id: CrateId( + 5, ), name: CrateName( "libc", @@ -1017,7 +1260,7 @@ fn cargo_hello_world_project_model() { is_proc_macro: false, }, CrateId( - 1, + 2, ): CrateData { root_file_id: FileId( 2, @@ -1080,7 +1323,7 @@ fn cargo_hello_world_project_model() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -1100,7 +1343,7 @@ fn cargo_hello_world_project_model() { is_proc_macro: false, }, CrateId( - 2, + 3, ): CrateData { root_file_id: FileId( 3, @@ -1120,13 +1363,11 @@ fn cargo_hello_world_project_model() { cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), potential_cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), target_layout: Err( @@ -1163,7 +1404,7 @@ fn cargo_hello_world_project_model() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -1183,7 +1424,7 @@ fn cargo_hello_world_project_model() { is_proc_macro: false, }, CrateId( - 3, + 4, ): CrateData { root_file_id: FileId( 4, @@ -1203,13 +1444,11 @@ fn cargo_hello_world_project_model() { cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), potential_cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), target_layout: Err( @@ -1246,7 +1485,7 @@ fn cargo_hello_world_project_model() { }, Dependency { crate_id: CrateId( - 4, + 5, ), name: CrateName( "libc", @@ -1266,7 +1505,7 @@ fn cargo_hello_world_project_model() { is_proc_macro: false, }, CrateId( - 4, + 5, ): CrateData { root_file_id: FileId( 5, From 1e58c0660549e1147b4749ab833609e046b2eac4 Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Sat, 18 Feb 2023 10:30:09 +1100 Subject: [PATCH 4/5] Apply overrides properly --- crates/project-model/src/tests.rs | 99 ++------------------------- crates/project-model/src/workspace.rs | 40 +++++++---- 2 files changed, 33 insertions(+), 106 deletions(-) diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index 85e03dd71159..024f69982029 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -176,7 +176,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { dependencies: [ Dependency { crate_id: CrateId( - 5, + 4, ), name: CrateName( "libc", @@ -197,89 +197,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { }, CrateId( 1, - ): CrateData { - root_file_id: FileId( - 1, - ), - edition: Edition2018, - version: Some( - "0.1.0", - ), - display_name: Some( - CrateDisplayName { - crate_name: CrateName( - "hello_world", - ), - canonical_name: "hello-world", - }, - ), - cfg_options: CfgOptions( - [ - "debug_assertions", - "test", - ], - ), - potential_cfg_options: CfgOptions( - [ - "debug_assertions", - "test", - ], - ), - target_layout: Err( - "target_data_layout not loaded", - ), - env: Env { - entries: { - "CARGO_PKG_LICENSE": "", - "CARGO_PKG_VERSION_MAJOR": "0", - "CARGO_MANIFEST_DIR": "$ROOT$hello-world", - "CARGO_PKG_VERSION": "0.1.0", - "CARGO_PKG_AUTHORS": "", - "CARGO_CRATE_NAME": "hello_world", - "CARGO_PKG_LICENSE_FILE": "", - "CARGO_PKG_HOMEPAGE": "", - "CARGO_PKG_DESCRIPTION": "", - "CARGO_PKG_NAME": "hello-world", - "CARGO_PKG_VERSION_PATCH": "0", - "CARGO": "cargo", - "CARGO_PKG_REPOSITORY": "", - "CARGO_PKG_VERSION_MINOR": "1", - "CARGO_PKG_VERSION_PRE": "", - }, - }, - dependencies: [ - Dependency { - crate_id: CrateId( - 0, - ), - name: CrateName( - "hello_world", - ), - prelude: true, - }, - Dependency { - crate_id: CrateId( - 5, - ), - name: CrateName( - "libc", - ), - prelude: true, - }, - ], - proc_macro: Err( - "crate has not (yet) been built", - ), - origin: CratesIo { - repo: None, - name: Some( - "hello-world", - ), - }, - is_proc_macro: false, - }, - CrateId( - 2, ): CrateData { root_file_id: FileId( 2, @@ -299,13 +216,11 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), potential_cfg_options: CfgOptions( [ "debug_assertions", - "test", ], ), target_layout: Err( @@ -342,7 +257,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { }, Dependency { crate_id: CrateId( - 5, + 4, ), name: CrateName( "libc", @@ -362,7 +277,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { is_proc_macro: false, }, CrateId( - 3, + 2, ): CrateData { root_file_id: FileId( 3, @@ -423,7 +338,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { }, Dependency { crate_id: CrateId( - 5, + 4, ), name: CrateName( "libc", @@ -443,7 +358,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { is_proc_macro: false, }, CrateId( - 4, + 3, ): CrateData { root_file_id: FileId( 4, @@ -504,7 +419,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { }, Dependency { crate_id: CrateId( - 5, + 4, ), name: CrateName( "libc", @@ -524,7 +439,7 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() { is_proc_macro: false, }, CrateId( - 5, + 4, ): CrateData { root_file_id: FileId( 5, diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 35ec83e1ebc8..d25a89ed6095 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -813,24 +813,11 @@ fn cargo_to_crate_graph( let mut has_private = false; // Next, create crates for each package, target pair for pkg in cargo.packages() { - let mut cfg_options = cfg_options.clone(); - let overrides = match override_cfg { CfgOverrides::Wildcard(cfg_diff) => Some(cfg_diff), CfgOverrides::Selective(cfg_overrides) => cfg_overrides.get(&cargo[pkg].name), }; - if let Some(overrides) = overrides { - // FIXME: this is sort of a hack to deal with #![cfg(not(test))] vanishing such as seen - // in ed25519_dalek (#7243), and libcore (#9203) (although you only hit that one while - // working on rust-lang/rust as that's the only time it appears outside sysroot). - // - // A more ideal solution might be to reanalyze crates based on where the cursor is and - // figure out the set of cfgs that would have to apply to make it active. - - cfg_options.apply_diff(overrides.clone()); - }; - has_private |= cargo[pkg].metadata.rustc_private; let mut lib_tgt = None; for &tgt in cargo[pkg].targets.iter() { @@ -885,6 +872,17 @@ fn cargo_to_crate_graph( cfg_options.insert_atom("test".into()); } + if let Some(overrides) = overrides { + // FIXME: this is sort of a hack to deal with #![cfg(not(test))] vanishing such as seen + // in ed25519_dalek (#7243), and libcore (#9203) (although you only hit that one while + // working on rust-lang/rust as that's the only time it appears outside sysroot). + // + // A more ideal solution might be to reanalyze crates based on where the cursor is and + // figure out the set of cfgs that would have to apply to make it active. + + cfg_options.apply_diff(overrides.clone()); + }; + let crate_id = add_crate(&cfg_options); if cargo[tgt].kind == TargetKind::Lib { @@ -902,7 +900,21 @@ fn cargo_to_crate_graph( // doesn't resolve dev-dependencies for packages outside the workspace and so // any unit tests that use them won't work properly. cfg_options.insert_atom("test".into()); - add_crate(&cfg_options); + + // Apply the overrides again, in case they disable cfg(test) + if let Some(overrides) = overrides { + cfg_options.apply_diff(overrides.clone()); + }; + + let test_cfg = CfgExpr::Atom(cfg::CfgAtom::Flag("test".into())); + // It the overrides disabled cfg(test), there's no reason for this extra version + // of the crate to exist. + if cfg_options + .check(&test_cfg) + .expect("cfg(test) was somehow an invalid cfg") + { + add_crate(&cfg_options); + } } } } From bd449f78484d6494ea8b974a8fb6d182e13f0f53 Mon Sep 17 00:00:00 2001 From: Liam Murphy Date: Sat, 18 Feb 2023 10:46:25 +1100 Subject: [PATCH 5/5] Don't make test lib target depend on lib target by default --- crates/project-model/src/tests.rs | 18 ------------------ crates/project-model/src/workspace.rs | 5 +++-- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index 024f69982029..b168a7c34b56 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -658,15 +658,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() { }, }, dependencies: [ - Dependency { - crate_id: CrateId( - 0, - ), - name: CrateName( - "hello_world", - ), - prelude: true, - }, Dependency { crate_id: CrateId( 5, @@ -1144,15 +1135,6 @@ fn cargo_hello_world_project_model() { }, }, dependencies: [ - Dependency { - crate_id: CrateId( - 0, - ), - name: CrateName( - "hello_world", - ), - prelude: true, - }, Dependency { crate_id: CrateId( 5, diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index d25a89ed6095..81b58c4c87a0 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -926,8 +926,9 @@ fn cargo_to_crate_graph( public_deps.add_to_crate_graph(&mut crate_graph, from); if let Some((to, name)) = lib_tgt.clone() { - if to != from && kind != TargetKind::BuildScript { - // (build script can not depend on its library target) + if !matches!(kind, TargetKind::BuildScript | TargetKind::Lib) { + // (build script can not depend on its library target, and library target does + // not depend on itself unless manually specified) // For root projects with dashes in their name, // cargo metadata does not do any normalization,