Unnamed repository; edit this file 'description' to name the repository.
Don't add --all-targets to runnables for no-std crates
Lukas Wirth 2023-05-28
parent 7c81fff · commit bbd9e41
-rw-r--r--crates/hir-def/src/nameres.rs10
-rw-r--r--crates/hir-def/src/nameres/collector.rs20
-rw-r--r--crates/hir-expand/src/name.rs2
-rw-r--r--crates/ide/src/lib.rs5
-rw-r--r--crates/rust-analyzer/src/cargo_target_spec.rs4
-rw-r--r--crates/rust-analyzer/src/handlers/request.rs19
6 files changed, 47 insertions, 13 deletions
diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs
index 8aceb4952a..ccb9bed5c5 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<SmolStr>,
/// #[rustc_coherence_is_core]
rustc_coherence_is_core: bool,
+ no_core: bool,
+ no_std: bool,
edition: Edition,
recursion_limit: Option<u32>,
@@ -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 c49bb248a7..64caf26299 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 0e95673dbd..f8dbb84277 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 4e5f01e716..c02dbc60a3 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<bool> {
+ 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<FileId> {
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 3035dc3330..c7b84c41b3 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<String>,
pub(crate) features: FxHashSet<String>,
}
@@ -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 eabc39b3e0..3f365c0594 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,