diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs | 92 |
1 files changed, 47 insertions, 45 deletions
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 01162b1a8..92b454150 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -1,6 +1,5 @@ //! See [`CargoWorkspace`]. -use std::iter; use std::path::PathBuf; use std::str::from_utf8; use std::{ops, process::Command}; @@ -10,7 +9,7 @@ use base_db::Edition; use cargo_metadata::{CargoOpt, MetadataCommand}; use la_arena::{Arena, Idx}; use paths::{AbsPath, AbsPathBuf}; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHashSet}; use serde::Deserialize; use serde_json::from_value; @@ -32,6 +31,7 @@ pub struct CargoWorkspace { packages: Arena<PackageData>, targets: Arena<TargetData>, workspace_root: AbsPathBuf, + target_directory: AbsPathBuf, } impl ops::Index<Package> for CargoWorkspace { @@ -57,20 +57,6 @@ pub enum RustLibSource { Discover, } -/// Crates to disable `#[cfg(test)]` on. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum UnsetTestCrates { - None, - Only(Vec<String>), - All, -} - -impl Default for UnsetTestCrates { - fn default() -> Self { - Self::None - } -} - #[derive(Clone, Debug, PartialEq, Eq)] pub enum CargoFeatures { All, @@ -99,8 +85,7 @@ pub struct CargoConfig { pub sysroot_src: Option<AbsPathBuf>, /// rustc private crate source pub rustc_source: Option<RustLibSource>, - /// crates to disable `#[cfg(test)]` on - pub unset_test_crates: UnsetTestCrates, + pub cfg_overrides: CfgOverrides, /// Invoke `cargo check` through the RUSTC_WRAPPER. pub wrap_rustc_in_build_scripts: bool, /// The command to run instead of `cargo check` for building build scripts. @@ -113,27 +98,6 @@ pub struct CargoConfig { pub invocation_location: InvocationLocation, } -impl CargoConfig { - pub fn cfg_overrides(&self) -> CfgOverrides { - match &self.unset_test_crates { - UnsetTestCrates::None => CfgOverrides::Selective(iter::empty().collect()), - UnsetTestCrates::Only(unset_test_crates) => CfgOverrides::Selective( - unset_test_crates - .iter() - .cloned() - .zip(iter::repeat_with(|| { - cfg::CfgDiff::new(Vec::new(), vec![cfg::CfgAtom::Flag("test".into())]) - .unwrap() - })) - .collect(), - ), - UnsetTestCrates::All => CfgOverrides::Wildcard( - cfg::CfgDiff::new(Vec::new(), vec![cfg::CfgAtom::Flag("test".into())]).unwrap(), - ), - } - } -} - pub type Package = Idx<PackageData>; pub type Target = Idx<TargetData>; @@ -293,13 +257,29 @@ impl CargoWorkspace { } meta.current_dir(current_dir.as_os_str()); + let mut other_options = vec![]; + // cargo metadata only supports a subset of flags of what cargo usually accepts, and usually + // the only relevant flags for metadata here are unstable ones, so we pass those along + // but nothing else + let mut extra_args = config.extra_args.iter(); + while let Some(arg) = extra_args.next() { + if arg == "-Z" { + if let Some(arg) = extra_args.next() { + other_options.push("-Z".to_owned()); + other_options.push(arg.to_owned()); + } + } + } + if !targets.is_empty() { - let other_options: Vec<_> = targets - .into_iter() - .flat_map(|target| ["--filter-platform".to_string(), target]) - .collect(); - meta.other_options(other_options); + other_options.append( + &mut targets + .into_iter() + .flat_map(|target| ["--filter-platform".to_owned().to_string(), target]) + .collect(), + ); } + meta.other_options(other_options); // FIXME: Fetching metadata is a slow process, as it might require // calling crates.io. We should be reporting progress here, but it's @@ -411,7 +391,10 @@ impl CargoWorkspace { let workspace_root = AbsPathBuf::assert(PathBuf::from(meta.workspace_root.into_os_string())); - CargoWorkspace { packages, targets, workspace_root } + let target_directory = + AbsPathBuf::assert(PathBuf::from(meta.target_directory.into_os_string())); + + CargoWorkspace { packages, targets, workspace_root, target_directory } } pub fn packages(&self) -> impl Iterator<Item = Package> + ExactSizeIterator + '_ { @@ -429,6 +412,10 @@ impl CargoWorkspace { &self.workspace_root } + pub fn target_directory(&self) -> &AbsPath { + &self.target_directory + } + pub fn package_flag(&self, package: &PackageData) -> String { if self.is_unique(&package.name) { package.name.clone() @@ -467,6 +454,21 @@ impl CargoWorkspace { 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 { self.packages.iter().filter(|(_, v)| v.name == name).count() == 1 } |