X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=crates%2Frust-analyzer%2Fsrc%2Fcargo_target_spec.rs;h=ec5dd16d001cdd38e0ea649b9619713f7af9f7c7;hb=0b53744f2d7e0694cd7207cca632fd6de1dc5bff;hp=5af0802a2f06363939782290d03fe5b048566431;hpb=f7a15b5cd1df58e46066bbd27c90cb1ad7f9c316;p=rust.git diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs index 5af0802a2f0..ec5dd16d001 100644 --- a/crates/rust-analyzer/src/cargo_target_spec.rs +++ b/crates/rust-analyzer/src/cargo_target_spec.rs @@ -1,8 +1,10 @@ //! See `CargoTargetSpec` +use std::mem; + use cfg::{CfgAtom, CfgExpr}; use ide::{FileId, RunnableKind, TestId}; -use project_model::{self, TargetKind}; +use project_model::{self, ManifestPath, TargetKind}; use vfs::AbsPathBuf; use crate::{global_state::GlobalStateSnapshot, Result}; @@ -14,21 +16,26 @@ #[derive(Clone)] pub(crate) struct CargoTargetSpec { pub(crate) workspace_root: AbsPathBuf, - pub(crate) cargo_toml: AbsPathBuf, + pub(crate) cargo_toml: ManifestPath, 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()); @@ -123,9 +136,10 @@ pub(crate) fn for_file( let res = CargoTargetSpec { workspace_root: cargo_ws.workspace_root().to_path_buf(), cargo_toml: package_data.manifest.clone(), - package: cargo_ws.package_flag(&package_data), + 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)) @@ -159,7 +173,7 @@ pub(crate) fn push_to(self, buf: &mut Vec, kind: &RunnableKind) { TargetKind::Lib => { buf.push("--lib".to_string()); } - TargetKind::Other => (), + TargetKind::Other | TargetKind::BuildScript => (), } } } @@ -191,7 +205,7 @@ mod tests { use super::*; use cfg::CfgExpr; - use mbe::ast_to_token_tree; + use mbe::syntax_node_to_token_tree; use syntax::{ ast::{self, AstNode}, SmolStr, @@ -201,7 +215,7 @@ fn check(cfg: &str, expected_features: &[&str]) { let cfg_expr = { let source_file = ast::SourceFile::parse(cfg).ok().unwrap(); let tt = source_file.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); - let (tt, _) = ast_to_token_tree(&tt).unwrap(); + let (tt, _) = syntax_node_to_token_tree(tt.syntax()); CfgExpr::parse(&tt) };