Skip to content

Commit 7c81fff

Browse files
committed
Auto merge of rust-lang#14910 - Veykril:cargo-features, r=Veykril
Filter out unused cargo features from config Closes rust-lang/rust-analyzer#11836
2 parents 9e6ae6b + 35b208a commit 7c81fff

File tree

6 files changed

+50
-12
lines changed

6 files changed

+50
-12
lines changed

.github/workflows/ci.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ jobs:
5858
uses: actions/checkout@v3
5959
with:
6060
ref: ${{ github.event.pull_request.head.sha }}
61-
fetch-depth: 20
6261

6362
- name: Install Rust toolchain
6463
run: |

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/project-model/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ serde.workspace = true
2121
triomphe.workspace = true
2222
anyhow = "1.0.62"
2323
la-arena = { version = "0.3.0", path = "../../lib/la-arena" }
24+
itertools = "0.10.5"
2425

2526
# local deps
2627
base-db.workspace = true

crates/project-model/src/build_scripts.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ use std::{
1414
};
1515

1616
use cargo_metadata::{camino::Utf8Path, Message};
17+
use itertools::Itertools;
1718
use la_arena::ArenaMap;
1819
use paths::{AbsPath, AbsPathBuf};
19-
use rustc_hash::FxHashMap;
20+
use rustc_hash::{FxHashMap, FxHashSet};
2021
use semver::Version;
2122
use serde::Deserialize;
2223

@@ -56,7 +57,10 @@ impl BuildScriptOutput {
5657
}
5758

5859
impl WorkspaceBuildScripts {
59-
fn build_command(config: &CargoConfig) -> io::Result<Command> {
60+
fn build_command(
61+
config: &CargoConfig,
62+
allowed_features: &FxHashSet<String>,
63+
) -> io::Result<Command> {
6064
let mut cmd = match config.run_build_script_command.as_deref() {
6165
Some([program, args @ ..]) => {
6266
let mut cmd = Command::new(program);
@@ -88,7 +92,12 @@ impl WorkspaceBuildScripts {
8892
}
8993
if !features.is_empty() {
9094
cmd.arg("--features");
91-
cmd.arg(features.join(" "));
95+
cmd.arg(
96+
features
97+
.iter()
98+
.filter(|&feat| allowed_features.contains(feat))
99+
.join(","),
100+
);
92101
}
93102
}
94103
}
@@ -127,13 +136,20 @@ impl WorkspaceBuildScripts {
127136
}
128137
.as_ref();
129138

130-
match Self::run_per_ws(Self::build_command(config)?, workspace, current_dir, progress) {
139+
let allowed_features = workspace.workspace_features();
140+
141+
match Self::run_per_ws(
142+
Self::build_command(config, &allowed_features)?,
143+
workspace,
144+
current_dir,
145+
progress,
146+
) {
131147
Ok(WorkspaceBuildScripts { error: Some(error), .. })
132148
if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
133149
{
134150
// building build scripts failed, attempt to build with --keep-going so
135151
// that we potentially get more build data
136-
let mut cmd = Self::build_command(config)?;
152+
let mut cmd = Self::build_command(config, &allowed_features)?;
137153
cmd.args(["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
138154
let mut res = Self::run_per_ws(cmd, workspace, current_dir, progress)?;
139155
res.error = Some(error);
@@ -161,7 +177,7 @@ impl WorkspaceBuildScripts {
161177
))
162178
}
163179
};
164-
let cmd = Self::build_command(config)?;
180+
let cmd = Self::build_command(config, &Default::default())?;
165181
// NB: Cargo.toml could have been modified between `cargo metadata` and
166182
// `cargo check`. We shouldn't assume that package ids we see here are
167183
// exactly those from `config`.

crates/project-model/src/cargo_workspace.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use base_db::Edition;
1010
use cargo_metadata::{CargoOpt, MetadataCommand};
1111
use la_arena::{Arena, Idx};
1212
use paths::{AbsPath, AbsPathBuf};
13-
use rustc_hash::FxHashMap;
13+
use rustc_hash::{FxHashMap, FxHashSet};
1414
use serde::Deserialize;
1515
use serde_json::from_value;
1616

@@ -491,6 +491,21 @@ impl CargoWorkspace {
491491
None
492492
}
493493

494+
/// Returns the union of the features of all member crates in this workspace.
495+
pub fn workspace_features(&self) -> FxHashSet<String> {
496+
self.packages()
497+
.filter_map(|package| {
498+
let package = &self[package];
499+
if package.is_member {
500+
Some(package.features.keys().cloned())
501+
} else {
502+
None
503+
}
504+
})
505+
.flatten()
506+
.collect()
507+
}
508+
494509
fn is_unique(&self, name: &str) -> bool {
495510
self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
496511
}

crates/rust-analyzer/src/cargo_target_spec.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::mem;
55
use cfg::{CfgAtom, CfgExpr};
66
use ide::{Cancellable, FileId, RunnableKind, TestId};
77
use project_model::{self, CargoFeatures, ManifestPath, TargetKind};
8+
use rustc_hash::FxHashSet;
89
use vfs::AbsPathBuf;
910

1011
use crate::global_state::GlobalStateSnapshot;
@@ -21,6 +22,7 @@ pub(crate) struct CargoTargetSpec {
2122
pub(crate) target: String,
2223
pub(crate) target_kind: TargetKind,
2324
pub(crate) required_features: Vec<String>,
25+
pub(crate) features: FxHashSet<String>,
2426
}
2527

2628
impl CargoTargetSpec {
@@ -73,12 +75,13 @@ impl CargoTargetSpec {
7375
}
7476
}
7577

76-
let target_required_features = if let Some(mut spec) = spec {
78+
let (allowed_features, target_required_features) = if let Some(mut spec) = spec {
79+
let allowed_features = mem::take(&mut spec.features);
7780
let required_features = mem::take(&mut spec.required_features);
7881
spec.push_to(&mut args, kind);
79-
required_features
82+
(allowed_features, required_features)
8083
} else {
81-
Vec::new()
84+
(Default::default(), Default::default())
8285
};
8386

8487
let cargo_config = snap.config.cargo();
@@ -97,7 +100,9 @@ impl CargoTargetSpec {
97100
required_features(cfg, &mut feats);
98101
}
99102

100-
feats.extend(features.iter().cloned());
103+
feats.extend(
104+
features.iter().filter(|&feat| allowed_features.contains(feat)).cloned(),
105+
);
101106
feats.extend(target_required_features);
102107

103108
feats.dedup();
@@ -136,6 +141,7 @@ impl CargoTargetSpec {
136141
target: target_data.name.clone(),
137142
target_kind: target_data.kind,
138143
required_features: target_data.required_features.clone(),
144+
features: package_data.features.keys().cloned().collect(),
139145
};
140146

141147
Ok(Some(res))

0 commit comments

Comments
 (0)