Skip to content

Commit bb13b88

Browse files
committed
Simplify feature representation in CargoConfig
1 parent 39eaf78 commit bb13b88

File tree

5 files changed

+105
-85
lines changed

5 files changed

+105
-85
lines changed

crates/project-model/src/build_scripts.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_hash::FxHashMap;
1515
use semver::Version;
1616
use serde::Deserialize;
1717

18-
use crate::{cfg_flag::CfgFlag, CargoConfig, CargoWorkspace, Package};
18+
use crate::{cfg_flag::CfgFlag, CargoConfig, CargoFeatures, CargoWorkspace, Package};
1919

2020
#[derive(Debug, Default, Clone, PartialEq, Eq)]
2121
pub struct WorkspaceBuildScripts {
@@ -61,15 +61,18 @@ impl WorkspaceBuildScripts {
6161
cmd.args(&["--target", target]);
6262
}
6363

64-
if config.all_features {
65-
cmd.arg("--all-features");
66-
} else {
67-
if config.no_default_features {
68-
cmd.arg("--no-default-features");
64+
match &config.features {
65+
CargoFeatures::All => {
66+
cmd.arg("--all-features");
6967
}
70-
if !config.features.is_empty() {
71-
cmd.arg("--features");
72-
cmd.arg(config.features.join(" "));
68+
CargoFeatures::Selected { features, no_default_features } => {
69+
if *no_default_features {
70+
cmd.arg("--no-default-features");
71+
}
72+
if !features.is_empty() {
73+
cmd.arg("--features");
74+
cmd.arg(features.join(" "));
75+
}
7376
}
7477
}
7578

crates/project-model/src/cargo_workspace.rs

+33-24
Original file line numberDiff line numberDiff line change
@@ -71,35 +71,41 @@ impl Default for UnsetTestCrates {
7171
}
7272
}
7373

74-
#[derive(Default, Clone, Debug, PartialEq, Eq)]
75-
pub struct CargoConfig {
76-
/// Do not activate the `default` feature.
77-
pub no_default_features: bool,
74+
#[derive(Clone, Debug, PartialEq, Eq)]
75+
pub enum CargoFeatures {
76+
All,
77+
Selected {
78+
/// List of features to activate.
79+
features: Vec<String>,
80+
/// Do not activate the `default` feature.
81+
no_default_features: bool,
82+
},
83+
}
7884

79-
/// Activate all available features
80-
pub all_features: bool,
85+
impl Default for CargoFeatures {
86+
fn default() -> Self {
87+
CargoFeatures::Selected { features: vec![], no_default_features: false }
88+
}
89+
}
8190

91+
#[derive(Default, Clone, Debug, PartialEq, Eq)]
92+
pub struct CargoConfig {
8293
/// List of features to activate.
83-
/// This will be ignored if `cargo_all_features` is true.
84-
pub features: Vec<String>,
85-
94+
pub features: CargoFeatures,
8695
/// rustc target
8796
pub target: Option<String>,
88-
8997
/// Don't load sysroot crates (`std`, `core` & friends). Might be useful
9098
/// when debugging isolated issues.
9199
pub no_sysroot: bool,
92-
93100
/// rustc private crate source
94101
pub rustc_source: Option<RustcSource>,
95-
96102
/// crates to disable `#[cfg(test)]` on
97103
pub unset_test_crates: UnsetTestCrates,
98-
104+
/// Invoke `cargo check` through the RUSTC_WRAPPER.
99105
pub wrap_rustc_in_build_scripts: bool,
100-
106+
/// The command to run instead of `cargo check` for building build scripts.
101107
pub run_build_script_command: Option<Vec<String>>,
102-
108+
/// Extra env vars to set when invoking the cargo command
103109
pub extra_env: FxHashMap<String, String>,
104110
}
105111

@@ -272,16 +278,19 @@ impl CargoWorkspace {
272278
let mut meta = MetadataCommand::new();
273279
meta.cargo_path(toolchain::cargo());
274280
meta.manifest_path(cargo_toml.to_path_buf());
275-
if config.all_features {
276-
meta.features(CargoOpt::AllFeatures);
277-
} else {
278-
if config.no_default_features {
279-
// FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures`
280-
// https://github.com/oli-obk/cargo_metadata/issues/79
281-
meta.features(CargoOpt::NoDefaultFeatures);
281+
match &config.features {
282+
CargoFeatures::All => {
283+
meta.features(CargoOpt::AllFeatures);
282284
}
283-
if !config.features.is_empty() {
284-
meta.features(CargoOpt::SomeFeatures(config.features.clone()));
285+
CargoFeatures::Selected { features, no_default_features } => {
286+
if *no_default_features {
287+
// FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures`
288+
// https://github.com/oli-obk/cargo_metadata/issues/79
289+
meta.features(CargoOpt::NoDefaultFeatures);
290+
}
291+
if !features.is_empty() {
292+
meta.features(CargoOpt::SomeFeatures(features.clone()));
293+
}
285294
}
286295
}
287296
meta.current_dir(current_dir.as_os_str());

crates/project-model/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ use rustc_hash::FxHashSet;
4242
pub use crate::{
4343
build_scripts::WorkspaceBuildScripts,
4444
cargo_workspace::{
45-
CargoConfig, CargoWorkspace, Package, PackageData, PackageDependency, RustcSource, Target,
46-
TargetData, TargetKind, UnsetTestCrates,
45+
CargoConfig, CargoFeatures, CargoWorkspace, Package, PackageData, PackageDependency,
46+
RustcSource, Target, TargetData, TargetKind, UnsetTestCrates,
4747
},
4848
manifest_path::ManifestPath,
4949
project_json::{ProjectJson, ProjectJsonData},

crates/rust-analyzer/src/cargo_target_spec.rs

+44-38
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::mem;
44

55
use cfg::{CfgAtom, CfgExpr};
66
use ide::{FileId, RunnableKind, TestId};
7-
use project_model::{self, ManifestPath, TargetKind};
7+
use project_model::{self, CargoFeatures, ManifestPath, TargetKind};
88
use vfs::AbsPathBuf;
99

1010
use crate::{global_state::GlobalStateSnapshot, Result};
@@ -35,41 +35,41 @@ impl CargoTargetSpec {
3535

3636
match kind {
3737
RunnableKind::Test { test_id, attr } => {
38-
args.push("test".to_string());
38+
args.push("test".to_owned());
3939
extra_args.push(test_id.to_string());
4040
if let TestId::Path(_) = test_id {
41-
extra_args.push("--exact".to_string());
41+
extra_args.push("--exact".to_owned());
4242
}
43-
extra_args.push("--nocapture".to_string());
43+
extra_args.push("--nocapture".to_owned());
4444
if attr.ignore {
45-
extra_args.push("--ignored".to_string());
45+
extra_args.push("--ignored".to_owned());
4646
}
4747
}
4848
RunnableKind::TestMod { path } => {
49-
args.push("test".to_string());
50-
extra_args.push(path.to_string());
51-
extra_args.push("--nocapture".to_string());
49+
args.push("test".to_owned());
50+
extra_args.push(path.clone());
51+
extra_args.push("--nocapture".to_owned());
5252
}
5353
RunnableKind::Bench { test_id } => {
54-
args.push("bench".to_string());
54+
args.push("bench".to_owned());
5555
extra_args.push(test_id.to_string());
5656
if let TestId::Path(_) = test_id {
57-
extra_args.push("--exact".to_string());
57+
extra_args.push("--exact".to_owned());
5858
}
59-
extra_args.push("--nocapture".to_string());
59+
extra_args.push("--nocapture".to_owned());
6060
}
6161
RunnableKind::DocTest { test_id } => {
62-
args.push("test".to_string());
63-
args.push("--doc".to_string());
62+
args.push("test".to_owned());
63+
args.push("--doc".to_owned());
6464
extra_args.push(test_id.to_string());
65-
extra_args.push("--nocapture".to_string());
65+
extra_args.push("--nocapture".to_owned());
6666
}
6767
RunnableKind::Bin => {
6868
let subcommand = match spec {
6969
Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => "test",
7070
_ => "run",
7171
};
72-
args.push(subcommand.to_string());
72+
args.push(subcommand.to_owned());
7373
}
7474
}
7575

@@ -82,29 +82,35 @@ impl CargoTargetSpec {
8282
};
8383

8484
let cargo_config = snap.config.cargo();
85-
if cargo_config.all_features {
86-
args.push("--all-features".to_string());
8785

88-
for feature in target_required_features {
89-
args.push("--features".to_string());
90-
args.push(feature);
91-
}
92-
} else {
93-
let mut features = Vec::new();
94-
if let Some(cfg) = cfg.as_ref() {
95-
required_features(cfg, &mut features);
86+
match &cargo_config.features {
87+
CargoFeatures::All => {
88+
args.push("--all-features".to_owned());
89+
for feature in target_required_features {
90+
args.push("--features".to_owned());
91+
args.push(feature);
92+
}
9693
}
94+
CargoFeatures::Selected { features, no_default_features } => {
95+
let mut feats = Vec::new();
96+
if let Some(cfg) = cfg.as_ref() {
97+
required_features(cfg, &mut feats);
98+
}
9799

98-
features.extend(cargo_config.features);
99-
features.extend(target_required_features);
100+
feats.extend(features.iter().cloned());
101+
feats.extend(target_required_features);
100102

101-
features.dedup();
102-
for feature in features {
103-
args.push("--features".to_string());
104-
args.push(feature);
103+
feats.dedup();
104+
for feature in feats {
105+
args.push("--features".to_owned());
106+
args.push(feature);
107+
}
108+
109+
if *no_default_features {
110+
args.push("--no-default-features".to_owned());
111+
}
105112
}
106113
}
107-
108114
Ok((args, extra_args))
109115
}
110116

@@ -136,7 +142,7 @@ impl CargoTargetSpec {
136142
}
137143

138144
pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) {
139-
buf.push("--package".to_string());
145+
buf.push("--package".to_owned());
140146
buf.push(self.package);
141147

142148
// Can't mix --doc with other target flags
@@ -145,23 +151,23 @@ impl CargoTargetSpec {
145151
}
146152
match self.target_kind {
147153
TargetKind::Bin => {
148-
buf.push("--bin".to_string());
154+
buf.push("--bin".to_owned());
149155
buf.push(self.target);
150156
}
151157
TargetKind::Test => {
152-
buf.push("--test".to_string());
158+
buf.push("--test".to_owned());
153159
buf.push(self.target);
154160
}
155161
TargetKind::Bench => {
156-
buf.push("--bench".to_string());
162+
buf.push("--bench".to_owned());
157163
buf.push(self.target);
158164
}
159165
TargetKind::Example => {
160-
buf.push("--example".to_string());
166+
buf.push("--example".to_owned());
161167
buf.push(self.target);
162168
}
163169
TargetKind::Lib => {
164-
buf.push("--lib".to_string());
170+
buf.push("--lib".to_owned());
165171
}
166172
TargetKind::Other | TargetKind::BuildScript => (),
167173
}

crates/rust-analyzer/src/config.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use ide_db::{
2222
use itertools::Itertools;
2323
use lsp_types::{ClientCapabilities, MarkupKind};
2424
use project_model::{
25-
CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource, UnsetTestCrates,
25+
CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource,
26+
UnsetTestCrates,
2627
};
2728
use rustc_hash::{FxHashMap, FxHashSet};
2829
use serde::{de::DeserializeOwned, Deserialize};
@@ -90,7 +91,7 @@ config_data! {
9091
/// List of features to activate.
9192
///
9293
/// Set this to `"all"` to pass `--all-features` to cargo.
93-
cargo_features: CargoFeatures = "[]",
94+
cargo_features: CargoFeaturesDef = "[]",
9495
/// Whether to pass `--no-default-features` to cargo.
9596
cargo_noDefaultFeatures: bool = "false",
9697
/// Internal config for debugging, disables loading of sysroot crates.
@@ -114,7 +115,7 @@ config_data! {
114115
/// `#rust-analyzer.cargo.features#`.
115116
///
116117
/// Set to `"all"` to pass `--all-features` to Cargo.
117-
checkOnSave_features: Option<CargoFeatures> = "null",
118+
checkOnSave_features: Option<CargoFeaturesDef> = "null",
118119
/// Whether to pass `--no-default-features` to Cargo. Defaults to
119120
/// `#rust-analyzer.cargo.noDefaultFeatures#`.
120121
checkOnSave_noDefaultFeatures: Option<bool> = "null",
@@ -1028,11 +1029,12 @@ impl Config {
10281029
});
10291030

10301031
CargoConfig {
1031-
no_default_features: self.data.cargo_noDefaultFeatures,
1032-
all_features: matches!(self.data.cargo_features, CargoFeatures::All),
10331032
features: match &self.data.cargo_features {
1034-
CargoFeatures::All => vec![],
1035-
CargoFeatures::Listed(it) => it.clone(),
1033+
CargoFeaturesDef::All => CargoFeatures::All,
1034+
CargoFeaturesDef::Selected(features) => CargoFeatures::Selected {
1035+
features: features.clone(),
1036+
no_default_features: self.data.cargo_noDefaultFeatures,
1037+
},
10361038
},
10371039
target: self.data.cargo_target.clone(),
10381040
no_sysroot: self.data.cargo_noSysroot,
@@ -1086,16 +1088,16 @@ impl Config {
10861088
.unwrap_or(self.data.cargo_noDefaultFeatures),
10871089
all_features: matches!(
10881090
self.data.checkOnSave_features.as_ref().unwrap_or(&self.data.cargo_features),
1089-
CargoFeatures::All
1091+
CargoFeaturesDef::All
10901092
),
10911093
features: match self
10921094
.data
10931095
.checkOnSave_features
10941096
.clone()
10951097
.unwrap_or_else(|| self.data.cargo_features.clone())
10961098
{
1097-
CargoFeatures::All => vec![],
1098-
CargoFeatures::Listed(it) => it,
1099+
CargoFeaturesDef::All => vec![],
1100+
CargoFeaturesDef::Selected(it) => it,
10991101
},
11001102
extra_args: self.data.checkOnSave_extraArgs.clone(),
11011103
extra_env: self.check_on_save_extra_env(),
@@ -1564,10 +1566,10 @@ enum CallableCompletionDef {
15641566

15651567
#[derive(Deserialize, Debug, Clone)]
15661568
#[serde(untagged)]
1567-
enum CargoFeatures {
1569+
enum CargoFeaturesDef {
15681570
#[serde(deserialize_with = "de_unit_v::all")]
15691571
All,
1570-
Listed(Vec<String>),
1572+
Selected(Vec<String>),
15711573
}
15721574

15731575
#[derive(Deserialize, Debug, Clone)]

0 commit comments

Comments
 (0)