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
This commit is contained in:
commit
7c81fff520
1
.github/workflows/ci.yaml
vendored
1
.github/workflows/ci.yaml
vendored
@ -58,7 +58,6 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
fetch-depth: 20
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
run: |
|
run: |
|
||||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1334,6 +1334,7 @@ dependencies = [
|
|||||||
"cargo_metadata",
|
"cargo_metadata",
|
||||||
"cfg",
|
"cfg",
|
||||||
"expect-test",
|
"expect-test",
|
||||||
|
"itertools",
|
||||||
"la-arena",
|
"la-arena",
|
||||||
"paths",
|
"paths",
|
||||||
"profile",
|
"profile",
|
||||||
|
@ -21,6 +21,7 @@ serde.workspace = true
|
|||||||
triomphe.workspace = true
|
triomphe.workspace = true
|
||||||
anyhow = "1.0.62"
|
anyhow = "1.0.62"
|
||||||
la-arena = { version = "0.3.0", path = "../../lib/la-arena" }
|
la-arena = { version = "0.3.0", path = "../../lib/la-arena" }
|
||||||
|
itertools = "0.10.5"
|
||||||
|
|
||||||
# local deps
|
# local deps
|
||||||
base-db.workspace = true
|
base-db.workspace = true
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
use cargo_metadata::{camino::Utf8Path, Message};
|
use cargo_metadata::{camino::Utf8Path, Message};
|
||||||
|
use itertools::Itertools;
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
use paths::{AbsPath, AbsPathBuf};
|
use paths::{AbsPath, AbsPathBuf};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@ -56,7 +57,10 @@ fn is_unchanged(&self) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WorkspaceBuildScripts {
|
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() {
|
let mut cmd = match config.run_build_script_command.as_deref() {
|
||||||
Some([program, args @ ..]) => {
|
Some([program, args @ ..]) => {
|
||||||
let mut cmd = Command::new(program);
|
let mut cmd = Command::new(program);
|
||||||
@ -88,7 +92,12 @@ fn build_command(config: &CargoConfig) -> io::Result<Command> {
|
|||||||
}
|
}
|
||||||
if !features.is_empty() {
|
if !features.is_empty() {
|
||||||
cmd.arg("--features");
|
cmd.arg("--features");
|
||||||
cmd.arg(features.join(" "));
|
cmd.arg(
|
||||||
|
features
|
||||||
|
.iter()
|
||||||
|
.filter(|&feat| allowed_features.contains(feat))
|
||||||
|
.join(","),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,13 +136,20 @@ pub(crate) fn run_for_workspace(
|
|||||||
}
|
}
|
||||||
.as_ref();
|
.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), .. })
|
Ok(WorkspaceBuildScripts { error: Some(error), .. })
|
||||||
if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
|
if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
|
||||||
{
|
{
|
||||||
// building build scripts failed, attempt to build with --keep-going so
|
// building build scripts failed, attempt to build with --keep-going so
|
||||||
// that we potentially get more build data
|
// 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");
|
cmd.args(["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
|
||||||
let mut res = Self::run_per_ws(cmd, workspace, current_dir, progress)?;
|
let mut res = Self::run_per_ws(cmd, workspace, current_dir, progress)?;
|
||||||
res.error = Some(error);
|
res.error = Some(error);
|
||||||
@ -161,7 +177,7 @@ pub(crate) fn run_once(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
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
|
// NB: Cargo.toml could have been modified between `cargo metadata` and
|
||||||
// `cargo check`. We shouldn't assume that package ids we see here are
|
// `cargo check`. We shouldn't assume that package ids we see here are
|
||||||
// exactly those from `config`.
|
// exactly those from `config`.
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
use cargo_metadata::{CargoOpt, MetadataCommand};
|
use cargo_metadata::{CargoOpt, MetadataCommand};
|
||||||
use la_arena::{Arena, Idx};
|
use la_arena::{Arena, Idx};
|
||||||
use paths::{AbsPath, AbsPathBuf};
|
use paths::{AbsPath, AbsPathBuf};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::from_value;
|
use serde_json::from_value;
|
||||||
|
|
||||||
@ -491,6 +491,21 @@ pub fn parent_manifests(&self, manifest_path: &ManifestPath) -> Option<Vec<Manif
|
|||||||
None
|
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 {
|
fn is_unique(&self, name: &str) -> bool {
|
||||||
self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
|
self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
use cfg::{CfgAtom, CfgExpr};
|
use cfg::{CfgAtom, CfgExpr};
|
||||||
use ide::{Cancellable, FileId, RunnableKind, TestId};
|
use ide::{Cancellable, FileId, RunnableKind, TestId};
|
||||||
use project_model::{self, CargoFeatures, ManifestPath, TargetKind};
|
use project_model::{self, CargoFeatures, ManifestPath, TargetKind};
|
||||||
|
use rustc_hash::FxHashSet;
|
||||||
use vfs::AbsPathBuf;
|
use vfs::AbsPathBuf;
|
||||||
|
|
||||||
use crate::global_state::GlobalStateSnapshot;
|
use crate::global_state::GlobalStateSnapshot;
|
||||||
@ -21,6 +22,7 @@ pub(crate) struct CargoTargetSpec {
|
|||||||
pub(crate) target: String,
|
pub(crate) target: String,
|
||||||
pub(crate) target_kind: TargetKind,
|
pub(crate) target_kind: TargetKind,
|
||||||
pub(crate) required_features: Vec<String>,
|
pub(crate) required_features: Vec<String>,
|
||||||
|
pub(crate) features: FxHashSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CargoTargetSpec {
|
impl CargoTargetSpec {
|
||||||
@ -73,12 +75,13 @@ pub(crate) fn runnable_args(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
let required_features = mem::take(&mut spec.required_features);
|
||||||
spec.push_to(&mut args, kind);
|
spec.push_to(&mut args, kind);
|
||||||
required_features
|
(allowed_features, required_features)
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
(Default::default(), Default::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
let cargo_config = snap.config.cargo();
|
let cargo_config = snap.config.cargo();
|
||||||
@ -97,7 +100,9 @@ pub(crate) fn runnable_args(
|
|||||||
required_features(cfg, &mut feats);
|
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.extend(target_required_features);
|
||||||
|
|
||||||
feats.dedup();
|
feats.dedup();
|
||||||
@ -136,6 +141,7 @@ pub(crate) fn for_file(
|
|||||||
target: target_data.name.clone(),
|
target: target_data.name.clone(),
|
||||||
target_kind: target_data.kind,
|
target_kind: target_data.kind,
|
||||||
required_features: target_data.required_features.clone(),
|
required_features: target_data.required_features.clone(),
|
||||||
|
features: package_data.features.keys().cloned().collect(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(res))
|
Ok(Some(res))
|
||||||
|
Loading…
Reference in New Issue
Block a user