summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
diff options
context:
space:
mode:
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.rs92
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
}