Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #14910 - Veykril:cargo-features, r=Veykril
Filter out unused cargo features from config Closes https://github.com/rust-lang/rust-analyzer/issues/11836
bors 2023-05-27
parent 9e6ae6b · parent 35b208a · commit 7c81fff
-rw-r--r--.github/workflows/ci.yaml1
-rw-r--r--Cargo.lock1
-rw-r--r--crates/project-model/Cargo.toml1
-rw-r--r--crates/project-model/src/build_scripts.rs28
-rw-r--r--crates/project-model/src/cargo_workspace.rs17
-rw-r--r--crates/rust-analyzer/src/cargo_target_spec.rs14
6 files changed, 50 insertions, 12 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 220d88afe4..622da105fd 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -58,7 +58,6 @@ jobs:
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- fetch-depth: 20
- name: Install Rust toolchain
run: |
diff --git a/Cargo.lock b/Cargo.lock
index e7ae42a2d9..f9c5417ffb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1334,6 +1334,7 @@ dependencies = [
"cargo_metadata",
"cfg",
"expect-test",
+ "itertools",
"la-arena",
"paths",
"profile",
diff --git a/crates/project-model/Cargo.toml b/crates/project-model/Cargo.toml
index efe61eb8f6..3abff64a83 100644
--- a/crates/project-model/Cargo.toml
+++ b/crates/project-model/Cargo.toml
@@ -21,6 +21,7 @@ serde.workspace = true
triomphe.workspace = true
anyhow = "1.0.62"
la-arena = { version = "0.3.0", path = "../../lib/la-arena" }
+itertools = "0.10.5"
# local deps
base-db.workspace = true
diff --git a/crates/project-model/src/build_scripts.rs b/crates/project-model/src/build_scripts.rs
index fe4cbfc886..6cbf403cb2 100644
--- a/crates/project-model/src/build_scripts.rs
+++ b/crates/project-model/src/build_scripts.rs
@@ -14,9 +14,10 @@ use std::{
};
use cargo_metadata::{camino::Utf8Path, Message};
+use itertools::Itertools;
use la_arena::ArenaMap;
use paths::{AbsPath, AbsPathBuf};
-use rustc_hash::FxHashMap;
+use rustc_hash::{FxHashMap, FxHashSet};
use semver::Version;
use serde::Deserialize;
@@ -56,7 +57,10 @@ impl BuildScriptOutput {
}
impl WorkspaceBuildScripts {
- fn build_command(config: &CargoConfig) -> io::Result<Command> {
+ fn build_command(
+ config: &CargoConfig,
+ allowed_features: &FxHashSet<String>,
+ ) -> io::Result<Command> {
let mut cmd = match config.run_build_script_command.as_deref() {
Some([program, args @ ..]) => {
let mut cmd = Command::new(program);
@@ -88,7 +92,12 @@ impl WorkspaceBuildScripts {
}
if !features.is_empty() {
cmd.arg("--features");
- cmd.arg(features.join(" "));
+ cmd.arg(
+ features
+ .iter()
+ .filter(|&feat| allowed_features.contains(feat))
+ .join(","),
+ );
}
}
}
@@ -127,13 +136,20 @@ impl WorkspaceBuildScripts {
}
.as_ref();
- match Self::run_per_ws(Self::build_command(config)?, workspace, current_dir, progress) {
+ let allowed_features = workspace.workspace_features();
+
+ match Self::run_per_ws(
+ Self::build_command(config, &allowed_features)?,
+ workspace,
+ current_dir,
+ progress,
+ ) {
Ok(WorkspaceBuildScripts { error: Some(error), .. })
if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
{
// building build scripts failed, attempt to build with --keep-going so
// that we potentially get more build data
- let mut cmd = Self::build_command(config)?;
+ let mut cmd = Self::build_command(config, &allowed_features)?;
cmd.args(["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
let mut res = Self::run_per_ws(cmd, workspace, current_dir, progress)?;
res.error = Some(error);
@@ -161,7 +177,7 @@ impl WorkspaceBuildScripts {
))
}
};
- let cmd = Self::build_command(config)?;
+ let cmd = Self::build_command(config, &Default::default())?;
// NB: Cargo.toml could have been modified between `cargo metadata` and
// `cargo check`. We shouldn't assume that package ids we see here are
// exactly those from `config`.
diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs
index e3fdeb448d..649a149504 100644
--- a/crates/project-model/src/cargo_workspace.rs
+++ b/crates/project-model/src/cargo_workspace.rs
@@ -10,7 +10,7 @@ use base_db::Edition;
use cargo_metadata::{CargoOpt, MetadataCommand};
use la_arena::{Arena, Idx};
use paths::{AbsPath, AbsPathBuf};
-use rustc_hash::FxHashMap;
+use rustc_hash::{FxHashMap, FxHashSet};
use serde::Deserialize;
use serde_json::from_value;
@@ -491,6 +491,21 @@ impl CargoWorkspace {
None
}
+ /// Returns the union of the features of all member crates in this workspace.
+ pub fn workspace_features(&self) -> FxHashSet<String> {
+ self.packages()
+ .filter_map(|package| {
+ let package = &self[package];
+ if package.is_member {
+ Some(package.features.keys().cloned())
+ } else {
+ None
+ }
+ })
+ .flatten()
+ .collect()
+ }
+
fn is_unique(&self, name: &str) -> bool {
self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
}
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs
index cf51cf15a0..3035dc3330 100644
--- a/crates/rust-analyzer/src/cargo_target_spec.rs
+++ b/crates/rust-analyzer/src/cargo_target_spec.rs
@@ -5,6 +5,7 @@ use std::mem;
use cfg::{CfgAtom, CfgExpr};
use ide::{Cancellable, FileId, RunnableKind, TestId};
use project_model::{self, CargoFeatures, ManifestPath, TargetKind};
+use rustc_hash::FxHashSet;
use vfs::AbsPathBuf;
use crate::global_state::GlobalStateSnapshot;
@@ -21,6 +22,7 @@ pub(crate) struct CargoTargetSpec {
pub(crate) target: String,
pub(crate) target_kind: TargetKind,
pub(crate) required_features: Vec<String>,
+ pub(crate) features: FxHashSet<String>,
}
impl CargoTargetSpec {
@@ -73,12 +75,13 @@ impl CargoTargetSpec {
}
}
- let target_required_features = if let Some(mut spec) = spec {
+ let (allowed_features, target_required_features) = if let Some(mut spec) = spec {
+ let allowed_features = mem::take(&mut spec.features);
let required_features = mem::take(&mut spec.required_features);
spec.push_to(&mut args, kind);
- required_features
+ (allowed_features, required_features)
} else {
- Vec::new()
+ (Default::default(), Default::default())
};
let cargo_config = snap.config.cargo();
@@ -97,7 +100,9 @@ impl CargoTargetSpec {
required_features(cfg, &mut feats);
}
- feats.extend(features.iter().cloned());
+ feats.extend(
+ features.iter().filter(|&feat| allowed_features.contains(feat)).cloned(),
+ );
feats.extend(target_required_features);
feats.dedup();
@@ -136,6 +141,7 @@ impl CargoTargetSpec {
target: target_data.name.clone(),
target_kind: target_data.kind,
required_features: target_data.required_features.clone(),
+ features: package_data.features.keys().cloned().collect(),
};
Ok(Some(res))