From bbd9e41606cba8efb02e356f78b7f1c8cfc04a94 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Fri, 26 May 2023 22:41:32 +0200 Subject: [PATCH] Don't add --all-targets to runnables for no-std crates --- crates/hir-def/src/nameres.rs | 10 ++++++++++ crates/hir-def/src/nameres/collector.rs | 20 ++++++++++++++----- crates/hir-expand/src/name.rs | 2 ++ crates/ide/src/lib.rs | 5 +++++ crates/rust-analyzer/src/cargo_target_spec.rs | 4 +++- crates/rust-analyzer/src/handlers/request.rs | 19 +++++++++++------- 6 files changed, 47 insertions(+), 13 deletions(-) diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 8aceb4952a54..ccb9bed5c501 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -127,6 +127,8 @@ pub struct DefMap { unstable_features: FxHashSet, /// #[rustc_coherence_is_core] rustc_coherence_is_core: bool, + no_core: bool, + no_std: bool, edition: Edition, recursion_limit: Option, @@ -294,6 +296,8 @@ impl DefMap { unstable_features: FxHashSet::default(), diagnostics: Vec::new(), rustc_coherence_is_core: false, + no_core: false, + no_std: false, } } @@ -331,6 +335,10 @@ impl DefMap { self.rustc_coherence_is_core } + pub fn is_no_std(&self) -> bool { + self.no_std || self.no_core + } + pub fn root(&self) -> LocalModuleId { self.root } @@ -528,6 +536,8 @@ impl DefMap { prelude: _, root: _, rustc_coherence_is_core: _, + no_core: _, + no_std: _, } = self; extern_prelude.shrink_to_fit(); diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index c49bb248a7b0..64caf26299ca 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs @@ -291,8 +291,6 @@ impl DefCollector<'_> { let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate); - self.inject_prelude(&attrs); - // Process other crate-level attributes. for attr in &*attrs { if let Some(cfg) = attr.cfg() { @@ -321,6 +319,16 @@ impl DefCollector<'_> { continue; } + if *attr_name == hir_expand::name![no_core] { + self.def_map.no_core = true; + continue; + } + + if *attr_name == hir_expand::name![no_std] { + self.def_map.no_std = true; + continue; + } + if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") { self.def_map.rustc_coherence_is_core = true; continue; @@ -359,6 +367,8 @@ impl DefCollector<'_> { } } + self.inject_prelude(); + ModCollector { def_collector: self, macro_depth: 0, @@ -517,15 +527,15 @@ impl DefCollector<'_> { } } - fn inject_prelude(&mut self, crate_attrs: &Attrs) { + fn inject_prelude(&mut self) { // See compiler/rustc_builtin_macros/src/standard_library_imports.rs - if crate_attrs.by_key("no_core").exists() { + if self.def_map.no_core { // libcore does not get a prelude. return; } - let krate = if crate_attrs.by_key("no_std").exists() { + let krate = if self.def_map.no_std { name![core] } else { let std = name![std]; diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs index 0e95673dbd43..f8dbb842775c 100644 --- a/crates/hir-expand/src/name.rs +++ b/crates/hir-expand/src/name.rs @@ -366,6 +366,8 @@ pub mod known { crate_type, derive, global_allocator, + no_core, + no_std, test, test_case, recursion_limit, diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 4e5f01e71669..c02dbc60a339 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -531,6 +531,11 @@ impl Analysis { self.with_db(|db| db.crate_graph()[crate_id].edition) } + /// Returns true if this crate has `no_std` or `no_core` specified. + pub fn is_crate_no_std(&self, crate_id: CrateId) -> Cancellable { + self.with_db(|db| hir::db::DefDatabase::crate_def_map(db, crate_id).is_no_std()) + } + /// Returns the root file of the given crate. pub fn crate_root(&self, crate_id: CrateId) -> Cancellable { self.with_db(|db| db.crate_graph()[crate_id].root_file_id) diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs index 3035dc333080..c7b84c41b33e 100644 --- a/crates/rust-analyzer/src/cargo_target_spec.rs +++ b/crates/rust-analyzer/src/cargo_target_spec.rs @@ -3,7 +3,7 @@ use std::mem; use cfg::{CfgAtom, CfgExpr}; -use ide::{Cancellable, FileId, RunnableKind, TestId}; +use ide::{Cancellable, CrateId, FileId, RunnableKind, TestId}; use project_model::{self, CargoFeatures, ManifestPath, TargetKind}; use rustc_hash::FxHashSet; use vfs::AbsPathBuf; @@ -21,6 +21,7 @@ pub(crate) struct CargoTargetSpec { pub(crate) package: String, pub(crate) target: String, pub(crate) target_kind: TargetKind, + pub(crate) crate_id: CrateId, pub(crate) required_features: Vec, pub(crate) features: FxHashSet, } @@ -142,6 +143,7 @@ impl CargoTargetSpec { target_kind: target_data.kind, required_features: target_data.required_features.clone(), features: package_data.features.keys().cloned().collect(), + crate_id, }; Ok(Some(res)) diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index eabc39b3e09c..3f365c05942f 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -768,20 +768,25 @@ pub(crate) fn handle_runnables( let config = snap.config.runnables(); match cargo_spec { Some(spec) => { + let all_targets = !snap.analysis.is_crate_no_std(spec.crate_id)?; for cmd in ["check", "test"] { + let mut cargo_args = + vec![cmd.to_owned(), "--package".to_owned(), spec.package.clone()]; + if all_targets { + cargo_args.push("--all-targets".to_owned()); + } res.push(lsp_ext::Runnable { - label: format!("cargo {cmd} -p {} --all-targets", spec.package), + label: format!( + "cargo {cmd} -p {}{all_targets}", + spec.package, + all_targets = if all_targets { " --all-targets" } else { "" } + ), location: None, kind: lsp_ext::RunnableKind::Cargo, args: lsp_ext::CargoRunnable { workspace_root: Some(spec.workspace_root.clone().into()), override_cargo: config.override_cargo.clone(), - cargo_args: vec![ - cmd.to_string(), - "--package".to_string(), - spec.package.clone(), - "--all-targets".to_string(), - ], + cargo_args, cargo_extra_args: config.cargo_extra_args.clone(), executable_args: Vec::new(), expect_test: None,