From 662dd7c27dff54a1bed9f8d85020dd8b6b055fd6 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 6 Feb 2022 18:56:25 +0300 Subject: [PATCH] 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. --- crates/project_model/src/cargo_workspace.rs | 3 +++ crates/rust-analyzer/src/cargo_target_spec.rs | 22 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index c2cf3c4ce3a..48051e4b5e8 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs @@ -210,6 +210,8 @@ pub struct TargetData { pub kind: TargetKind, /// Is this target a proc-macro pub is_proc_macro: bool, + /// Required features of the target without which it won't build + pub required_features: Vec, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -348,6 +350,7 @@ pub fn new(mut meta: cargo_metadata::Metadata) -> CargoWorkspace { root: AbsPathBuf::assert(PathBuf::from(&meta_tgt.src_path)), kind: TargetKind::new(meta_tgt.kind.as_slice()), is_proc_macro, + required_features: meta_tgt.required_features.clone(), }); pkg_data.targets.push(tgt); } diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs index a8894e0f022..ec5dd16d001 100644 --- a/crates/rust-analyzer/src/cargo_target_spec.rs +++ b/crates/rust-analyzer/src/cargo_target_spec.rs @@ -1,5 +1,7 @@ //! See `CargoTargetSpec` +use std::mem; + use cfg::{CfgAtom, CfgExpr}; use ide::{FileId, RunnableKind, TestId}; use project_model::{self, ManifestPath, TargetKind}; @@ -18,17 +20,22 @@ pub(crate) struct CargoTargetSpec { pub(crate) package: String, pub(crate) target: String, pub(crate) target_kind: TargetKind, + pub(crate) required_features: Vec, } impl CargoTargetSpec { pub(crate) fn runnable_args( snap: &GlobalStateSnapshot, - spec: Option, + mut spec: Option, kind: &RunnableKind, cfg: &Option, ) -> Result<(Vec, Vec)> { let mut args = Vec::new(); let mut extra_args = Vec::new(); + + let target_required_features = + spec.as_mut().map(|spec| mem::take(&mut spec.required_features)).unwrap_or(Vec::new()); + match kind { RunnableKind::Test { test_id, attr } => { args.push("test".to_string()); @@ -87,14 +94,20 @@ pub(crate) fn runnable_args( let cargo_config = snap.config.cargo(); if cargo_config.all_features { args.push("--all-features".to_string()); + + for feature in target_required_features { + args.push("--features".to_string()); + args.push(feature); + } } else { let mut features = Vec::new(); if let Some(cfg) = cfg.as_ref() { required_features(cfg, &mut features); } - for feature in cargo_config.features { - features.push(feature.clone()); - } + + features.extend(cargo_config.features); + features.extend(target_required_features); + features.dedup(); for feature in features { args.push("--features".to_string()); @@ -126,6 +139,7 @@ pub(crate) fn for_file( package: cargo_ws.package_flag(package_data), target: target_data.name.clone(), target_kind: target_data.kind, + required_features: target_data.required_features.clone(), }; Ok(Some(res)) -- 2.44.0