diff --git a/crates/cfg/src/lib.rs b/crates/cfg/src/lib.rs index e9daaf7de3..c2d4008605 100644 --- a/crates/cfg/src/lib.rs +++ b/crates/cfg/src/lib.rs @@ -49,6 +49,10 @@ impl CfgOptions { cfg.fold(&|atom| self.enabled.contains(atom)) } + pub fn check_atom(&self, cfg: &CfgAtom) -> bool { + self.enabled.contains(cfg) + } + pub fn insert_atom(&mut self, key: Symbol) { self.enabled.insert(CfgAtom::Flag(key)); } diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index e09ef4f205..7f1d19719d 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -6,7 +6,7 @@ use std::{cmp::Ordering, iter, mem, ops::Not}; use base_db::{CrateId, CrateOrigin, Dependency, LangCrateOrigin}; -use cfg::{CfgExpr, CfgOptions}; +use cfg::{CfgAtom, CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ attrs::{Attr, AttrId}, @@ -1324,13 +1324,21 @@ impl DefCollector<'_> { }; // Skip #[test]/#[bench] expansion, which would merely result in more memory usage - // due to duplicating functions into macro expansions + // due to duplicating functions into macro expansions, but only if `cfg(test)` is active, + // otherwise they are expanded to nothing and this can impact e.g. diagnostics (due to things + // being cfg'ed out). + // Ideally we will just expand them to nothing here. But we are only collecting macro calls, + // not expanding them, so we have no way to do that. if matches!( def.kind, MacroDefKind::BuiltInAttr(_, expander) if expander.is_test() || expander.is_bench() ) { - return recollect_without(self); + let test_is_active = + self.cfg_options.check_atom(&CfgAtom::Flag(sym::test.clone())); + if test_is_active { + return recollect_without(self); + } } let call_id = || { diff --git a/crates/hir-expand/src/builtin/attr_macro.rs b/crates/hir-expand/src/builtin/attr_macro.rs index b9afc666f7..2a8691b461 100644 --- a/crates/hir-expand/src/builtin/attr_macro.rs +++ b/crates/hir-expand/src/builtin/attr_macro.rs @@ -4,6 +4,8 @@ use span::{MacroCallId, Span}; use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind}; +use super::quote; + macro_rules! register_builtin { ($(($name:ident, $variant:ident) => $expand:ident),* ) => { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -52,15 +54,15 @@ impl BuiltinAttrExpander { } register_builtin! { - (bench, Bench) => dummy_attr_expand, + (bench, Bench) => dummy_gate_test_expand, (cfg_accessible, CfgAccessible) => dummy_attr_expand, (cfg_eval, CfgEval) => dummy_attr_expand, (derive, Derive) => derive_expand, // derive const is equivalent to derive for our proposes. (derive_const, DeriveConst) => derive_expand, (global_allocator, GlobalAllocator) => dummy_attr_expand, - (test, Test) => dummy_attr_expand, - (test_case, TestCase) => dummy_attr_expand + (test, Test) => dummy_gate_test_expand, + (test_case, TestCase) => dummy_gate_test_expand } pub fn find_builtin_attr(ident: &name::Name) -> Option { @@ -76,6 +78,19 @@ fn dummy_attr_expand( ExpandResult::ok(tt.clone()) } +fn dummy_gate_test_expand( + _db: &dyn ExpandDatabase, + _id: MacroCallId, + tt: &tt::Subtree, + span: Span, +) -> ExpandResult { + let result = quote::quote! { span=> + #[cfg(test)] + #tt + }; + ExpandResult::ok(result) +} + /// We generate a very specific expansion here, as we do not actually expand the `#[derive]` attribute /// itself in name res, but we do want to expand it to something for the IDE layer, so that the input /// derive attributes can be downmapped, and resolved as proper paths. diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs index 409f532c3e..0e1606a699 100644 --- a/crates/load-cargo/src/lib.rs +++ b/crates/load-cargo/src/lib.rs @@ -30,7 +30,6 @@ pub struct LoadCargoConfig { pub load_out_dirs_from_check: bool, pub with_proc_macro_server: ProcMacroServerChoice, pub prefill_caches: bool, - pub set_test: bool, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -100,7 +99,6 @@ pub fn load_workspace( vfs.file_id(&path) }, extra_env, - load_config.set_test, ); let proc_macros = { let proc_macro_server = match &proc_macro_server { @@ -528,12 +526,11 @@ mod tests { #[test] fn test_loading_rust_analyzer() { let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); - let cargo_config = CargoConfig::default(); + let cargo_config = CargoConfig { set_test: true, ..CargoConfig::default() }; let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: false, with_proc_macro_server: ProcMacroServerChoice::None, prefill_caches: false, - set_test: true, }; let (db, _vfs, _proc_macro) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {}).unwrap(); diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs index 7cc21bcf13..2dc6f0357e 100644 --- a/crates/project-model/src/cargo_workspace.rs +++ b/crates/project-model/src/cargo_workspace.rs @@ -100,6 +100,7 @@ pub struct CargoConfig { pub invocation_strategy: InvocationStrategy, /// Optional path to use instead of `target` when building pub target_dir: Option, + pub set_test: bool, } pub type Package = Idx; diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs index cccfe3bb51..5099697a69 100644 --- a/crates/project-model/src/tests.rs +++ b/crates/project-model/src/tests.rs @@ -35,6 +35,7 @@ fn load_cargo_with_overrides( rustc: Err(None), cargo_config_extra_env: Default::default(), error: None, + set_test: true, }, cfg_overrides, sysroot: Sysroot::empty(), @@ -136,7 +137,6 @@ fn to_crate_graph(project_workspace: ProjectWorkspace) -> (CrateGraph, ProcMacro } }, &Default::default(), - true, ) } @@ -243,6 +243,7 @@ fn smoke_test_real_sysroot_cargo() { rustc: Err(None), cargo_config_extra_env: Default::default(), error: None, + set_test: true, }, sysroot, rustc_cfg: Vec::new(), @@ -258,6 +259,5 @@ fn smoke_test_real_sysroot_cargo() { } }, &Default::default(), - true, ); } diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index ed1f607309..71b9b61e20 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -78,6 +78,7 @@ pub enum ProjectWorkspaceKind { rustc: Result, Option>, /// Environment variables set in the `.cargo/config` file. cargo_config_extra_env: FxHashMap, + set_test: bool, }, /// Project workspace was specified using a `rust-project.json` file. Json(ProjectJson), @@ -98,6 +99,7 @@ pub enum ProjectWorkspaceKind { cargo: Option<(CargoWorkspace, WorkspaceBuildScripts, Option>)>, /// Environment variables set in the `.cargo/config` file. cargo_config_extra_env: FxHashMap, + set_test: bool, }, } @@ -112,6 +114,7 @@ impl fmt::Debug for ProjectWorkspace { build_scripts, rustc, cargo_config_extra_env, + set_test, } => f .debug_struct("Cargo") .field("root", &cargo.workspace_root().file_name()) @@ -126,6 +129,7 @@ impl fmt::Debug for ProjectWorkspace { .field("toolchain", &toolchain) .field("data_layout", &target_layout) .field("cargo_config_extra_env", &cargo_config_extra_env) + .field("set_test", set_test) .field("build_scripts", &build_scripts.error().unwrap_or("ok")) .finish(), ProjectWorkspaceKind::Json(project) => { @@ -137,12 +141,14 @@ impl fmt::Debug for ProjectWorkspace { .field("toolchain", &toolchain) .field("data_layout", &target_layout) .field("n_cfg_overrides", &cfg_overrides.len()); + debug_struct.finish() } ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, cargo_config_extra_env, + set_test, } => f .debug_struct("DetachedFiles") .field("file", &file) @@ -154,6 +160,7 @@ impl fmt::Debug for ProjectWorkspace { .field("data_layout", &target_layout) .field("n_cfg_overrides", &cfg_overrides.len()) .field("cargo_config_extra_env", &cargo_config_extra_env) + .field("set_test", set_test) .finish(), } } @@ -329,6 +336,7 @@ impl ProjectWorkspace { rustc, cargo_config_extra_env, error: error.map(Arc::new), + set_test: config.set_test, }, sysroot, rustc_cfg, @@ -423,6 +431,7 @@ impl ProjectWorkspace { file: detached_file.to_owned(), cargo: cargo_script, cargo_config_extra_env, + set_test: config.set_test, }, sysroot, rustc_cfg, @@ -609,6 +618,7 @@ impl ProjectWorkspace { build_scripts, cargo_config_extra_env: _, error: _, + set_test: _, } => { cargo .packages() @@ -728,7 +738,6 @@ impl ProjectWorkspace { &self, load: FileLoader<'_>, extra_env: &FxHashMap, - set_test: bool, ) -> (CrateGraph, ProcMacroPaths) { let _p = tracing::info_span!("ProjectWorkspace::to_crate_graph").entered(); @@ -742,7 +751,6 @@ impl ProjectWorkspace { sysroot, extra_env, cfg_overrides, - set_test, ), sysroot, ), @@ -752,6 +760,7 @@ impl ProjectWorkspace { build_scripts, cargo_config_extra_env: _, error: _, + set_test, } => ( cargo_to_crate_graph( load, @@ -761,11 +770,11 @@ impl ProjectWorkspace { rustc_cfg.clone(), cfg_overrides, build_scripts, - set_test, + *set_test, ), sysroot, ), - ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, .. } => ( + ProjectWorkspaceKind::DetachedFile { file, cargo: cargo_script, set_test, .. } => ( if let Some((cargo, build_scripts, _)) = cargo_script { cargo_to_crate_graph( &mut |path| load(path), @@ -775,7 +784,7 @@ impl ProjectWorkspace { rustc_cfg.clone(), cfg_overrides, build_scripts, - set_test, + *set_test, ) } else { detached_file_to_crate_graph( @@ -784,7 +793,7 @@ impl ProjectWorkspace { file, sysroot, cfg_overrides, - set_test, + *set_test, ) }, sysroot, @@ -818,6 +827,7 @@ impl ProjectWorkspace { cargo_config_extra_env, build_scripts: _, error: _, + set_test: _, }, ProjectWorkspaceKind::Cargo { cargo: o_cargo, @@ -825,6 +835,7 @@ impl ProjectWorkspace { cargo_config_extra_env: o_cargo_config_extra_env, build_scripts: _, error: _, + set_test: _, }, ) => { cargo == o_cargo @@ -839,11 +850,13 @@ impl ProjectWorkspace { file, cargo: Some((cargo_script, _, _)), cargo_config_extra_env, + set_test: _, }, ProjectWorkspaceKind::DetachedFile { file: o_file, cargo: Some((o_cargo_script, _, _)), cargo_config_extra_env: o_cargo_config_extra_env, + set_test: _, }, ) => { file == o_file @@ -875,12 +888,11 @@ fn project_json_to_crate_graph( sysroot: &Sysroot, extra_env: &FxHashMap, override_cfg: &CfgOverrides, - set_test: bool, ) -> (CrateGraph, ProcMacroPaths) { let mut res = (CrateGraph::default(), ProcMacroPaths::default()); let (crate_graph, proc_macros) = &mut res; let (public_deps, libproc_macro) = - sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load, set_test); + sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); let r_a_cfg_flag = CfgAtom::Flag(sym::rust_analyzer.clone()); let mut cfg_cache: FxHashMap<&str, Vec> = FxHashMap::default(); @@ -1000,7 +1012,7 @@ fn cargo_to_crate_graph( let crate_graph = &mut res.0; let proc_macros = &mut res.1; let (public_deps, libproc_macro) = - sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load, set_test); + sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load); let cfg_options = CfgOptions::from_iter(rustc_cfg); @@ -1187,7 +1199,7 @@ fn detached_file_to_crate_graph( let _p = tracing::info_span!("detached_file_to_crate_graph").entered(); let mut crate_graph = CrateGraph::default(); let (public_deps, _libproc_macro) = - sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load, set_test); + sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load); let mut cfg_options = CfgOptions::from_iter(rustc_cfg); if set_test { @@ -1416,7 +1428,6 @@ fn sysroot_to_crate_graph( sysroot: &Sysroot, rustc_cfg: Vec, load: FileLoader<'_>, - set_test: bool, ) -> (SysrootPublicDeps, Option) { let _p = tracing::info_span!("sysroot_to_crate_graph").entered(); match sysroot.mode() { @@ -1439,7 +1450,7 @@ fn sysroot_to_crate_graph( ..Default::default() }, &WorkspaceBuildScripts::default(), - set_test, + false, ); let mut pub_deps = vec![]; diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 033a7d10d9..9a484a5a5b 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -65,6 +65,7 @@ impl flags::AnalysisStats { false => Some(RustLibSource::Discover), }, all_targets: true, + set_test: true, ..Default::default() }; let no_progress = &|_| (); @@ -84,7 +85,6 @@ impl flags::AnalysisStats { ProcMacroServerChoice::Sysroot }, prefill_caches: false, - set_test: true, }; let build_scripts_time = if self.disable_build_scripts { diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs index 91fa312f33..28f25975d6 100644 --- a/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/crates/rust-analyzer/src/cli/diagnostics.rs @@ -39,8 +39,6 @@ impl flags::Diagnostics { load_out_dirs_from_check: !self.disable_build_scripts, with_proc_macro_server, prefill_caches: false, - // We don't pass `--all-targets` so we also set `cfg(test)` to false. - set_test: false, }; let (db, _vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/crates/rust-analyzer/src/cli/lsif.rs b/crates/rust-analyzer/src/cli/lsif.rs index 197dbd8614..ca8acf57bf 100644 --- a/crates/rust-analyzer/src/cli/lsif.rs +++ b/crates/rust-analyzer/src/cli/lsif.rs @@ -277,6 +277,7 @@ impl flags::Lsif { let cargo_config = &CargoConfig { sysroot: Some(RustLibSource::Discover), all_targets: true, + set_test: true, ..Default::default() }; let no_progress = &|_| (); @@ -284,7 +285,6 @@ impl flags::Lsif { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, - set_test: true, }; let path = AbsPathBuf::assert_utf8(env::current_dir()?.join(self.path)); let root = ProjectManifest::discover_single(&path)?; diff --git a/crates/rust-analyzer/src/cli/run_tests.rs b/crates/rust-analyzer/src/cli/run_tests.rs index 3afee41580..11534bbeba 100644 --- a/crates/rust-analyzer/src/cli/run_tests.rs +++ b/crates/rust-analyzer/src/cli/run_tests.rs @@ -16,13 +16,13 @@ impl flags::RunTests { let cargo_config = CargoConfig { sysroot: Some(RustLibSource::Discover), all_targets: true, + set_test: true, ..Default::default() }; let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, - set_test: true, }; let (ref db, _vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; diff --git a/crates/rust-analyzer/src/cli/rustc_tests.rs b/crates/rust-analyzer/src/cli/rustc_tests.rs index 0c148be1da..30378db0b3 100644 --- a/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -70,6 +70,7 @@ impl Tester { let cargo_config = CargoConfig { sysroot: Some(RustLibSource::Discover), all_targets: true, + set_test: true, ..Default::default() }; @@ -85,6 +86,7 @@ impl Tester { file: ManifestPath::try_from(tmp_file).unwrap(), cargo: None, cargo_config_extra_env: Default::default(), + set_test: true, }, sysroot, rustc_cfg: vec![], @@ -96,7 +98,6 @@ impl Tester { load_out_dirs_from_check: false, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, - set_test: true, }; let (db, _vfs, _proc_macro) = load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config)?; diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs index 3d704d6f03..ff009e6954 100644 --- a/crates/rust-analyzer/src/cli/scip.rs +++ b/crates/rust-analyzer/src/cli/scip.rs @@ -50,7 +50,6 @@ impl flags::Scip { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, - set_test: config.cfg_set_test(None), }; let cargo_config = config.cargo(None); let (db, vfs, _) = load_workspace_at( diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs index 3a463b822f..c03688e800 100644 --- a/crates/rust-analyzer/src/cli/ssr.rs +++ b/crates/rust-analyzer/src/cli/ssr.rs @@ -13,13 +13,13 @@ impl flags::Ssr { let cargo_config = CargoConfig { sysroot: Some(RustLibSource::Discover), all_targets: true, + set_test: true, ..Default::default() }; let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, - set_test: true, }; let (ref db, vfs, _proc_macro) = load_workspace_at( &std::env::current_dir()?, @@ -51,12 +51,12 @@ impl flags::Search { pub fn run(self) -> anyhow::Result<()> { use ide_db::base_db::SourceRootDatabase; use ide_db::symbol_index::SymbolsDatabase; - let cargo_config = CargoConfig { all_targets: true, ..CargoConfig::default() }; + let cargo_config = + CargoConfig { all_targets: true, set_test: true, ..CargoConfig::default() }; let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, - set_test: true, }; let (ref db, _vfs, _proc_macro) = load_workspace_at( &std::env::current_dir()?, diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 97799abb14..2be71ef92a 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -1861,9 +1861,14 @@ impl Config { extra_args: self.cargo_extraArgs(source_root).clone(), extra_env: self.cargo_extraEnv(source_root).clone(), target_dir: self.target_dir_from_config(source_root), + set_test: *self.cfg_setTest(source_root), } } + pub fn cfg_set_test(&self, source_root: Option) -> bool { + *self.cfg_setTest(source_root) + } + pub(crate) fn completion_snippets_default() -> FxHashMap { serde_json::from_str( r#"{ diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs index b98da50b42..8a4f9d49fe 100644 --- a/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/crates/rust-analyzer/src/integrated_benchmarks.rs @@ -37,13 +37,13 @@ fn integrated_highlighting_benchmark() { let cargo_config = CargoConfig { sysroot: Some(project_model::RustLibSource::Discover), all_targets: true, + set_test: true, ..CargoConfig::default() }; let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, - set_test: true, }; let (db, vfs, _proc_macro) = { @@ -105,13 +105,13 @@ fn integrated_completion_benchmark() { let cargo_config = CargoConfig { sysroot: Some(project_model::RustLibSource::Discover), all_targets: true, + set_test: true, ..CargoConfig::default() }; let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, - set_test: true, }; let (db, vfs, _proc_macro) = { @@ -284,13 +284,13 @@ fn integrated_diagnostics_benchmark() { let cargo_config = CargoConfig { sysroot: Some(project_model::RustLibSource::Discover), all_targets: true, + set_test: true, ..CargoConfig::default() }; let load_cargo_config = LoadCargoConfig { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, - set_test: true, }; let (db, vfs, _proc_macro) = { diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 830a3d7f3d..7a1782e565 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -703,12 +703,7 @@ impl GlobalState { vfs.file_id(&vfs_path) }; - ws_to_crate_graph( - &self.workspaces, - self.config.extra_env(None), - load, - self.config.cfg_set_test(None), - ) + ws_to_crate_graph(&self.workspaces, self.config.extra_env(None), load) }; let mut change = ChangeWithProcMacros::new(); if self.config.expand_proc_macros() { @@ -861,13 +856,12 @@ pub fn ws_to_crate_graph( workspaces: &[ProjectWorkspace], extra_env: &FxHashMap, mut load: impl FnMut(&AbsPath) -> Option, - set_test: bool, ) -> (CrateGraph, Vec, FxHashMap>) { let mut crate_graph = CrateGraph::default(); let mut proc_macro_paths = Vec::default(); let mut ws_data = FxHashMap::default(); for ws in workspaces { - let (other, mut crate_proc_macros) = ws.to_crate_graph(&mut load, extra_env, set_test); + let (other, mut crate_proc_macros) = ws.to_crate_graph(&mut load, extra_env); let ProjectWorkspace { toolchain, target_layout, .. } = ws; let mapping = crate_graph.extend(other, &mut crate_proc_macros);