From 74880a10ae581118e26696cb28b9dcfb0d792e07 Mon Sep 17 00:00:00 2001 From: Vincent Esche Date: Mon, 23 Aug 2021 19:18:11 +0200 Subject: [PATCH] Extend `CargoConfig.unset_test_crates` to allow for efficiently disabling `#[cfg(test)]` on all crates without having to first load the crate graph --- crates/project_model/src/cargo_workspace.rs | 39 +- crates/project_model/src/lib.rs | 2 +- crates/project_model/src/tests.rs | 903 +++++++++++++++++++- crates/project_model/src/workspace.rs | 35 +- crates/rust-analyzer/src/config.rs | 8 +- 5 files changed, 972 insertions(+), 15 deletions(-) diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index 22cd4a708280..caf6b6f3b9c2 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs @@ -57,6 +57,20 @@ pub enum RustcSource { Discover, } +/// Crates to disable `#[cfg(test)]` on. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum UnsetTestCrates { + None, + Only(Vec), + All, +} + +impl Default for UnsetTestCrates { + fn default() -> Self { + Self::None + } +} + #[derive(Default, Clone, Debug, PartialEq, Eq)] pub struct CargoConfig { /// Do not activate the `default` feature. @@ -80,20 +94,29 @@ pub struct CargoConfig { pub rustc_source: Option, /// crates to disable `#[cfg(test)]` on - pub unset_test_crates: Vec, + pub unset_test_crates: UnsetTestCrates, pub wrap_rustc_in_build_scripts: bool, } impl CargoConfig { pub fn cfg_overrides(&self) -> CfgOverrides { - self.unset_test_crates - .iter() - .cloned() - .zip(iter::repeat_with(|| { - cfg::CfgDiff::new(Vec::new(), vec![cfg::CfgAtom::Flag("test".into())]).unwrap() - })) - .collect() + match &self.unset_test_crates { + UnsetTestCrates::None => CfgOverrides::Selective(iter::empty().collect()), + UnsetTestCrates::Only(unset_test_crates) => CfgOverrides::Selective( + unset_test_crates + .iter() + .map(|name| name.clone()) + .zip(iter::repeat_with(|| { + cfg::CfgDiff::new(Vec::new(), vec![cfg::CfgAtom::Flag("test".into())]) + .unwrap() + })) + .collect(), + ), + UnsetTestCrates::All => CfgOverrides::Wildcard( + cfg::CfgDiff::new(Vec::new(), vec![cfg::CfgAtom::Flag("test".into())]).unwrap(), + ), + } } } diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs index e0fd75fcdcae..e1bc5fe86bea 100644 --- a/crates/project_model/src/lib.rs +++ b/crates/project_model/src/lib.rs @@ -42,7 +42,7 @@ pub use crate::{ build_scripts::WorkspaceBuildScripts, cargo_workspace::{ CargoConfig, CargoWorkspace, Package, PackageData, PackageDependency, RustcSource, Target, - TargetData, TargetKind, + TargetData, TargetKind, UnsetTestCrates, }, manifest_path::ManifestPath, project_json::{ProjectJson, ProjectJsonData}, diff --git a/crates/project_model/src/tests.rs b/crates/project_model/src/tests.rs index f2c998308f3e..840bc281fca7 100644 --- a/crates/project_model/src/tests.rs +++ b/crates/project_model/src/tests.rs @@ -4,6 +4,7 @@ use std::{ }; use base_db::{CrateGraph, FileId}; +use cfg::{CfgAtom, CfgDiff}; use expect_test::{expect, Expect}; use paths::{AbsPath, AbsPathBuf}; use serde::de::DeserializeOwned; @@ -14,6 +15,10 @@ use crate::{ }; fn load_cargo(file: &str) -> CrateGraph { + load_cargo_with_overrides(file, CfgOverrides::default()) +} + +fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGraph { let meta = get_test_json_file(file); let cargo_workspace = CargoWorkspace::new(meta); let project_workspace = ProjectWorkspace::Cargo { @@ -22,7 +27,7 @@ fn load_cargo(file: &str) -> CrateGraph { sysroot: None, rustc: None, rustc_cfg: Vec::new(), - cfg_overrides: CfgOverrides::default(), + cfg_overrides, }; to_crate_graph(project_workspace) } @@ -99,6 +104,902 @@ fn check_crate_graph(crate_graph: CrateGraph, expect: Expect) { expect.assert_eq(&crate_graph); } +#[test] +fn cargo_hello_world_project_model_with_wildcard_overrides() { + let cfg_overrides = CfgOverrides::Wildcard( + CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(), + ); + let crate_graph = load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides); + check_crate_graph( + crate_graph, + expect![[r#" + CrateGraph { + arena: { + CrateId( + 0, + ): CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2018, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + 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( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + CrateId( + 5, + ): CrateData { + root_file_id: FileId( + 6, + ), + edition: Edition2015, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "const_fn", + ), + canonical_name: "const_fn", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=default", + "feature=std", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + ], + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", + "CARGO_PKG_VERSION": "0.2.98", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "libc", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "libc", + "CARGO_PKG_VERSION_PATCH": "98", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "2", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [ + Dependency { + crate_id: CrateId( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + CrateId( + 2, + ): CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2018, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "an_example", + ), + canonical_name: "an-example", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + 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", + ), + }, + Dependency { + crate_id: CrateId( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + CrateId( + 4, + ): CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2015, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "libc", + ), + canonical_name: "libc", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=default", + "feature=std", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + ], + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", + "CARGO_PKG_VERSION": "0.2.98", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "libc", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "libc", + "CARGO_PKG_VERSION_PATCH": "98", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "2", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [], + proc_macro: [], + }, + CrateId( + 1, + ): CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2018, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "hello_world", + ), + canonical_name: "hello-world", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + 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", + ), + }, + Dependency { + crate_id: CrateId( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + CrateId( + 6, + ): CrateData { + root_file_id: FileId( + 7, + ), + edition: Edition2015, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "build_script_build", + ), + canonical_name: "build-script-build", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=default", + "feature=std", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + ], + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", + "CARGO_PKG_VERSION": "0.2.98", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "libc", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "libc", + "CARGO_PKG_VERSION_PATCH": "98", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "2", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [], + proc_macro: [], + }, + CrateId( + 3, + ): CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2018, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "it", + ), + canonical_name: "it", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + ], + ), + 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", + ), + }, + Dependency { + crate_id: CrateId( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + }, + }"#]], + ) +} + +#[test] +fn cargo_hello_world_project_model_with_selective_overrides() { + let cfg_overrides = { + CfgOverrides::Selective( + std::iter::once(( + "libc".to_owned(), + CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(), + )) + .collect(), + ) + }; + let crate_graph = load_cargo_with_overrides("hello-world-metadata.json", cfg_overrides); + check_crate_graph( + crate_graph, + expect![[r#" + CrateGraph { + arena: { + CrateId( + 0, + ): CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2018, + 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", + ], + ), + 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( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + CrateId( + 5, + ): CrateData { + root_file_id: FileId( + 6, + ), + edition: Edition2015, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "const_fn", + ), + canonical_name: "const_fn", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=default", + "feature=std", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + ], + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", + "CARGO_PKG_VERSION": "0.2.98", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "libc", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "libc", + "CARGO_PKG_VERSION_PATCH": "98", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "2", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [ + Dependency { + crate_id: CrateId( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + CrateId( + 2, + ): CrateData { + root_file_id: FileId( + 3, + ), + edition: Edition2018, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "an_example", + ), + canonical_name: "an-example", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "test", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "test", + ], + ), + 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", + ), + }, + Dependency { + crate_id: CrateId( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + CrateId( + 4, + ): CrateData { + root_file_id: FileId( + 5, + ), + edition: Edition2015, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "libc", + ), + canonical_name: "libc", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=default", + "feature=std", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + ], + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", + "CARGO_PKG_VERSION": "0.2.98", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "libc", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "libc", + "CARGO_PKG_VERSION_PATCH": "98", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "2", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [], + proc_macro: [], + }, + CrateId( + 1, + ): CrateData { + root_file_id: FileId( + 2, + ), + edition: Edition2018, + 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", + ], + ), + 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", + ), + }, + Dependency { + crate_id: CrateId( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + CrateId( + 6, + ): CrateData { + root_file_id: FileId( + 7, + ), + edition: Edition2015, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "build_script_build", + ), + canonical_name: "build-script-build", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=default", + "feature=std", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "feature=align", + "feature=const-extern-fn", + "feature=default", + "feature=extra_traits", + "feature=rustc-dep-of-std", + "feature=std", + "feature=use_std", + ], + ), + env: Env { + entries: { + "CARGO_PKG_LICENSE": "", + "CARGO_PKG_VERSION_MAJOR": "0", + "CARGO_MANIFEST_DIR": "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", + "CARGO_PKG_VERSION": "0.2.98", + "CARGO_PKG_AUTHORS": "", + "CARGO_CRATE_NAME": "libc", + "CARGO_PKG_LICENSE_FILE": "", + "CARGO_PKG_HOMEPAGE": "", + "CARGO_PKG_DESCRIPTION": "", + "CARGO_PKG_NAME": "libc", + "CARGO_PKG_VERSION_PATCH": "98", + "CARGO": "cargo", + "CARGO_PKG_REPOSITORY": "", + "CARGO_PKG_VERSION_MINOR": "2", + "CARGO_PKG_VERSION_PRE": "", + }, + }, + dependencies: [], + proc_macro: [], + }, + CrateId( + 3, + ): CrateData { + root_file_id: FileId( + 4, + ), + edition: Edition2018, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "it", + ), + canonical_name: "it", + }, + ), + cfg_options: CfgOptions( + [ + "debug_assertions", + "test", + ], + ), + potential_cfg_options: CfgOptions( + [ + "debug_assertions", + "test", + ], + ), + 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", + ), + }, + Dependency { + crate_id: CrateId( + 4, + ), + name: CrateName( + "libc", + ), + }, + ], + proc_macro: [], + }, + }, + }"#]], + ) +} + #[test] fn cargo_hello_world_project_model() { let crate_graph = load_cargo("hello-world-metadata.json"); diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index d911209b075b..c138a4b1b79f 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs @@ -21,7 +21,32 @@ use crate::{ TargetKind, WorkspaceBuildScripts, }; -pub type CfgOverrides = FxHashMap; +/// A set of cfg-overrides per crate. +/// +/// `Wildcard(..)` is useful e.g. disabling `#[cfg(test)]` on all crates, +/// without having to first obtain a list of all crates. +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum CfgOverrides { + /// A single global set of overrides matching all crates. + Wildcard(CfgDiff), + /// A set of overrides matching specific crates. + Selective(FxHashMap), +} + +impl Default for CfgOverrides { + fn default() -> Self { + Self::Selective(FxHashMap::default()) + } +} + +impl CfgOverrides { + pub fn len(&self) -> usize { + match self { + CfgOverrides::Wildcard(_) => 1, + CfgOverrides::Selective(hash_map) => hash_map.len(), + } + } +} /// `PackageRoot` describes a package root folder. /// Which may be an external dependency, or a member of @@ -501,7 +526,13 @@ fn cargo_to_crate_graph( for pkg in cargo.packages() { let mut cfg_options = &cfg_options; let mut replaced_cfg_options; - if let Some(overrides) = override_cfg.get(&cargo[pkg].name) { + + 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). diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 22da92779efa..ae841ba11821 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -19,7 +19,9 @@ use ide_db::helpers::{ SnippetCap, }; use lsp_types::{ClientCapabilities, MarkupKind}; -use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource}; +use project_model::{ + CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource, UnsetTestCrates, +}; use rustc_hash::{FxHashMap, FxHashSet}; use serde::{de::DeserializeOwned, Deserialize}; use vfs::AbsPathBuf; @@ -666,9 +668,9 @@ impl Config { all_features: self.data.cargo_allFeatures, features: self.data.cargo_features.clone(), target: self.data.cargo_target.clone(), - rustc_source, no_sysroot: self.data.cargo_noSysroot, - unset_test_crates: self.data.cargo_unsetTest.clone(), + rustc_source, + unset_test_crates: UnsetTestCrates::Only(self.data.cargo_unsetTest.clone()), wrap_rustc_in_build_scripts: self.data.cargo_useRustcWrapperForBuildScripts, } }