Skip to content

Commit 662dd7c

Browse files
committed
Pass required features to cargo when using run action
When using `F1`->`Rust Analyzer: Run` action on an `example`, pass its `required-features` to `cargo run`. This allows to run examples that were otherwise impossible to run with RA.
1 parent ba33054 commit 662dd7c

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

crates/project_model/src/cargo_workspace.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ pub struct TargetData {
210210
pub kind: TargetKind,
211211
/// Is this target a proc-macro
212212
pub is_proc_macro: bool,
213+
/// Required features of the target without which it won't build
214+
pub required_features: Vec<String>,
213215
}
214216

215217
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -348,6 +350,7 @@ impl CargoWorkspace {
348350
root: AbsPathBuf::assert(PathBuf::from(&meta_tgt.src_path)),
349351
kind: TargetKind::new(meta_tgt.kind.as_slice()),
350352
is_proc_macro,
353+
required_features: meta_tgt.required_features.clone(),
351354
});
352355
pkg_data.targets.push(tgt);
353356
}

crates/rust-analyzer/src/cargo_target_spec.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! See `CargoTargetSpec`
22
3+
use std::mem;
4+
35
use cfg::{CfgAtom, CfgExpr};
46
use ide::{FileId, RunnableKind, TestId};
57
use project_model::{self, ManifestPath, TargetKind};
@@ -18,17 +20,22 @@ pub(crate) struct CargoTargetSpec {
1820
pub(crate) package: String,
1921
pub(crate) target: String,
2022
pub(crate) target_kind: TargetKind,
23+
pub(crate) required_features: Vec<String>,
2124
}
2225

2326
impl CargoTargetSpec {
2427
pub(crate) fn runnable_args(
2528
snap: &GlobalStateSnapshot,
26-
spec: Option<CargoTargetSpec>,
29+
mut spec: Option<CargoTargetSpec>,
2730
kind: &RunnableKind,
2831
cfg: &Option<CfgExpr>,
2932
) -> Result<(Vec<String>, Vec<String>)> {
3033
let mut args = Vec::new();
3134
let mut extra_args = Vec::new();
35+
36+
let target_required_features =
37+
spec.as_mut().map(|spec| mem::take(&mut spec.required_features)).unwrap_or(Vec::new());
38+
3239
match kind {
3340
RunnableKind::Test { test_id, attr } => {
3441
args.push("test".to_string());
@@ -87,14 +94,20 @@ impl CargoTargetSpec {
8794
let cargo_config = snap.config.cargo();
8895
if cargo_config.all_features {
8996
args.push("--all-features".to_string());
97+
98+
for feature in target_required_features {
99+
args.push("--features".to_string());
100+
args.push(feature);
101+
}
90102
} else {
91103
let mut features = Vec::new();
92104
if let Some(cfg) = cfg.as_ref() {
93105
required_features(cfg, &mut features);
94106
}
95-
for feature in cargo_config.features {
96-
features.push(feature.clone());
97-
}
107+
108+
features.extend(cargo_config.features);
109+
features.extend(target_required_features);
110+
98111
features.dedup();
99112
for feature in features {
100113
args.push("--features".to_string());
@@ -126,6 +139,7 @@ impl CargoTargetSpec {
126139
package: cargo_ws.package_flag(package_data),
127140
target: target_data.name.clone(),
128141
target_kind: target_data.kind,
142+
required_features: target_data.required_features.clone(),
129143
};
130144

131145
Ok(Some(res))

0 commit comments

Comments
 (0)