Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/project-model/src/cargo_workspace.rs105
-rw-r--r--crates/project-model/src/lib.rs16
-rw-r--r--crates/project-model/src/sysroot.rs31
-rw-r--r--crates/project-model/src/target_triple.rs82
-rw-r--r--crates/project-model/src/tests.rs4
-rw-r--r--crates/project-model/src/workspace.rs83
-rw-r--r--crates/rust-analyzer/src/bin/main.rs6
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs9
-rw-r--r--crates/rust-analyzer/src/cli/rustc_tests.rs2
-rw-r--r--crates/rust-analyzer/src/config.rs11
10 files changed, 209 insertions, 140 deletions
diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs
index ba4946bf0b..836879c75b 100644
--- a/crates/project-model/src/cargo_workspace.rs
+++ b/crates/project-model/src/cargo_workspace.rs
@@ -13,8 +13,8 @@ use serde_json::from_value;
use span::Edition;
use toolchain::Tool;
-use crate::{utf8_stdout, ManifestPath, Sysroot, SysrootQueryMetadata};
use crate::{CfgOverrides, InvocationStrategy};
+use crate::{ManifestPath, Sysroot, SysrootQueryMetadata};
/// [`CargoWorkspace`] represents the logical structure of, well, a Cargo
/// workspace. It pretty closely mirrors `cargo metadata` output.
@@ -251,6 +251,18 @@ impl TargetKind {
}
}
+#[derive(Default, Clone, Debug, PartialEq, Eq)]
+pub struct CargoMetadataConfig {
+ /// List of features to activate.
+ pub features: CargoFeatures,
+ /// rustc targets
+ pub targets: Vec<String>,
+ /// Extra args to pass to the cargo command.
+ pub extra_args: Vec<String>,
+ /// Extra env vars to set when invoking the cargo command
+ pub extra_env: FxHashMap<String, String>,
+}
+
// Deserialize helper for the cargo metadata
#[derive(Deserialize, Default)]
struct PackageMetadata {
@@ -265,7 +277,7 @@ impl CargoWorkspace {
pub fn fetch_metadata(
cargo_toml: &ManifestPath,
current_dir: &AbsPath,
- config: &CargoConfig,
+ config: &CargoMetadataConfig,
sysroot: &Sysroot,
locked: bool,
progress: &dyn Fn(String),
@@ -276,14 +288,12 @@ impl CargoWorkspace {
fn fetch_metadata_(
cargo_toml: &ManifestPath,
current_dir: &AbsPath,
- config: &CargoConfig,
+ config: &CargoMetadataConfig,
sysroot: &Sysroot,
locked: bool,
no_deps: bool,
progress: &dyn Fn(String),
) -> anyhow::Result<(cargo_metadata::Metadata, Option<anyhow::Error>)> {
- let targets = find_list_of_build_targets(config, cargo_toml, sysroot);
-
let cargo = sysroot.tool(Tool::Cargo);
let mut meta = MetadataCommand::new();
meta.cargo_path(cargo.get_program());
@@ -319,12 +329,9 @@ impl CargoWorkspace {
}
}
- if !targets.is_empty() {
- other_options.append(
- &mut targets
- .into_iter()
- .flat_map(|target| ["--filter-platform".to_owned(), target])
- .collect(),
+ if !config.targets.is_empty() {
+ other_options.extend(
+ config.targets.iter().flat_map(|it| ["--filter-platform".to_owned(), it.clone()]),
);
}
// The manifest is a rust file, so this means its a script manifest
@@ -596,79 +603,3 @@ impl CargoWorkspace {
self.is_virtual_workspace
}
}
-
-fn find_list_of_build_targets(
- config: &CargoConfig,
- cargo_toml: &ManifestPath,
- sysroot: &Sysroot,
-) -> Vec<String> {
- if let Some(target) = &config.target {
- return [target.into()].to_vec();
- }
-
- let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env, sysroot);
- if !build_targets.is_empty() {
- return build_targets;
- }
-
- rustc_discover_host_triple(cargo_toml, &config.extra_env, sysroot).into_iter().collect()
-}
-
-fn rustc_discover_host_triple(
- cargo_toml: &ManifestPath,
- extra_env: &FxHashMap<String, String>,
- sysroot: &Sysroot,
-) -> Option<String> {
- let mut rustc = sysroot.tool(Tool::Rustc);
- rustc.envs(extra_env);
- rustc.current_dir(cargo_toml.parent()).arg("-vV");
- tracing::debug!("Discovering host platform by {:?}", rustc);
- match utf8_stdout(rustc) {
- Ok(stdout) => {
- let field = "host: ";
- let target = stdout.lines().find_map(|l| l.strip_prefix(field));
- if let Some(target) = target {
- Some(target.to_owned())
- } else {
- // If we fail to resolve the host platform, it's not the end of the world.
- tracing::info!("rustc -vV did not report host platform, got:\n{}", stdout);
- None
- }
- }
- Err(e) => {
- tracing::warn!("Failed to discover host platform: {}", e);
- None
- }
- }
-}
-
-fn cargo_config_build_target(
- cargo_toml: &ManifestPath,
- extra_env: &FxHashMap<String, String>,
- sysroot: &Sysroot,
-) -> Vec<String> {
- let mut cargo_config = sysroot.tool(Tool::Cargo);
- cargo_config.envs(extra_env);
- cargo_config
- .current_dir(cargo_toml.parent())
- .args(["-Z", "unstable-options", "config", "get", "build.target"])
- .env("RUSTC_BOOTSTRAP", "1");
- // if successful we receive `build.target = "target-triple"`
- // or `build.target = ["<target 1>", ..]`
- tracing::debug!("Discovering cargo config target by {:?}", cargo_config);
- utf8_stdout(cargo_config).map(parse_output_cargo_config_build_target).unwrap_or_default()
-}
-
-fn parse_output_cargo_config_build_target(stdout: String) -> Vec<String> {
- let trimmed = stdout.trim_start_matches("build.target = ").trim_matches('"');
-
- if !trimmed.starts_with('[') {
- return [trimmed.to_owned()].to_vec();
- }
-
- let res = serde_json::from_str(trimmed);
- if let Err(e) = &res {
- tracing::warn!("Failed to parse `build.target` as an array of target: {}`", e);
- }
- res.unwrap_or_default()
-}
diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs
index da8afc5d3a..9a024f6b96 100644
--- a/crates/project-model/src/lib.rs
+++ b/crates/project-model/src/lib.rs
@@ -23,6 +23,7 @@ pub mod project_json;
mod rustc_cfg;
mod sysroot;
pub mod target_data_layout;
+mod target_triple;
mod workspace;
#[cfg(test)]
@@ -42,8 +43,8 @@ use rustc_hash::FxHashSet;
pub use crate::{
build_dependencies::WorkspaceBuildScripts,
cargo_workspace::{
- CargoConfig, CargoFeatures, CargoWorkspace, Package, PackageData, PackageDependency,
- RustLibSource, Target, TargetData, TargetKind,
+ CargoConfig, CargoFeatures, CargoMetadataConfig, CargoWorkspace, Package, PackageData,
+ PackageDependency, RustLibSource, Target, TargetData, TargetKind,
},
manifest_path::ManifestPath,
project_json::{ProjectJson, ProjectJsonData},
@@ -241,9 +242,14 @@ fn parse_cfg(s: &str) -> Result<cfg::CfgAtom, String> {
Ok(res)
}
-#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SysrootQueryMetadata {
- #[default]
- CargoMetadata,
+ CargoMetadata(CargoMetadataConfig),
None,
}
+
+impl Default for SysrootQueryMetadata {
+ fn default() -> Self {
+ SysrootQueryMetadata::CargoMetadata(Default::default())
+ }
+}
diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs
index 8426e689a6..d8186a23f7 100644
--- a/crates/project-model/src/sysroot.rs
+++ b/crates/project-model/src/sysroot.rs
@@ -14,7 +14,10 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
use rustc_hash::FxHashMap;
use toolchain::{probe_for_binary, Tool};
-use crate::{utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath, SysrootQueryMetadata};
+use crate::{
+ cargo_workspace::CargoMetadataConfig, utf8_stdout, CargoWorkspace, ManifestPath,
+ SysrootQueryMetadata,
+};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Sysroot {
@@ -126,7 +129,7 @@ impl Sysroot {
pub fn discover(
dir: &AbsPath,
extra_env: &FxHashMap<String, String>,
- sysroot_query_metadata: SysrootQueryMetadata,
+ sysroot_query_metadata: &SysrootQueryMetadata,
) -> Sysroot {
let sysroot_dir = discover_sysroot_dir(dir, extra_env);
let sysroot_src_dir = sysroot_dir.as_ref().ok().map(|sysroot_dir| {
@@ -139,7 +142,7 @@ impl Sysroot {
current_dir: &AbsPath,
extra_env: &FxHashMap<String, String>,
sysroot_src_dir: AbsPathBuf,
- sysroot_query_metadata: SysrootQueryMetadata,
+ sysroot_query_metadata: &SysrootQueryMetadata,
) -> Sysroot {
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env);
Sysroot::load_core_check(
@@ -151,7 +154,7 @@ impl Sysroot {
pub fn discover_sysroot_src_dir(
sysroot_dir: AbsPathBuf,
- sysroot_query_metadata: SysrootQueryMetadata,
+ sysroot_query_metadata: &SysrootQueryMetadata,
) -> Sysroot {
let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir)
.ok_or_else(|| format_err!("can't find standard library sources in {sysroot_dir}"));
@@ -205,7 +208,7 @@ impl Sysroot {
pub fn load(
sysroot_dir: Option<AbsPathBuf>,
sysroot_src_dir: Option<AbsPathBuf>,
- sysroot_query_metadata: SysrootQueryMetadata,
+ sysroot_query_metadata: &SysrootQueryMetadata,
) -> Sysroot {
Self::load_core_check(sysroot_dir.map(Ok), sysroot_src_dir.map(Ok), sysroot_query_metadata)
}
@@ -213,7 +216,7 @@ impl Sysroot {
fn load_core_check(
sysroot_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
sysroot_src_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
- sysroot_query_metadata: SysrootQueryMetadata,
+ sysroot_query_metadata: &SysrootQueryMetadata,
) -> Sysroot {
let mut sysroot = Self::load_(sysroot_dir, sysroot_src_dir, sysroot_query_metadata);
if sysroot.error.is_none() {
@@ -241,7 +244,7 @@ impl Sysroot {
fn load_(
sysroot_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
sysroot_src_dir: Option<Result<AbsPathBuf, anyhow::Error>>,
- sysroot_query_metadata: SysrootQueryMetadata,
+ sysroot_query_metadata: &SysrootQueryMetadata,
) -> Sysroot {
let sysroot_dir = match sysroot_dir {
Some(Ok(sysroot_dir)) => Some(sysroot_dir),
@@ -274,13 +277,16 @@ impl Sysroot {
}
}
};
- if sysroot_query_metadata == SysrootQueryMetadata::CargoMetadata {
+ if let SysrootQueryMetadata::CargoMetadata(cargo_config) = sysroot_query_metadata {
let library_manifest =
ManifestPath::try_from(sysroot_src_dir.join("Cargo.toml")).unwrap();
if fs::metadata(&library_manifest).is_ok() {
- if let Some(sysroot) =
- Self::load_library_via_cargo(library_manifest, &sysroot_dir, &sysroot_src_dir)
- {
+ if let Some(sysroot) = Self::load_library_via_cargo(
+ library_manifest,
+ &sysroot_dir,
+ &sysroot_src_dir,
+ cargo_config,
+ ) {
return sysroot;
}
}
@@ -341,9 +347,10 @@ impl Sysroot {
library_manifest: ManifestPath,
sysroot_dir: &Option<AbsPathBuf>,
sysroot_src_dir: &AbsPathBuf,
+ cargo_config: &CargoMetadataConfig,
) -> Option<Sysroot> {
tracing::debug!("Loading library metadata: {library_manifest}");
- let mut cargo_config = CargoConfig::default();
+ let mut cargo_config = cargo_config.clone();
// the sysroot uses `public-dependency`, so we make cargo think it's a nightly
cargo_config.extra_env.insert(
"__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS".to_owned(),
diff --git a/crates/project-model/src/target_triple.rs b/crates/project-model/src/target_triple.rs
new file mode 100644
index 0000000000..92e0c49885
--- /dev/null
+++ b/crates/project-model/src/target_triple.rs
@@ -0,0 +1,82 @@
+//! Runs `rustc --print -vV` to get the host target.
+use anyhow::Context;
+use rustc_hash::FxHashMap;
+use toolchain::Tool;
+
+use crate::{utf8_stdout, ManifestPath, Sysroot};
+
+pub(super) enum TargetTipleConfig<'a> {
+ #[expect(dead_code)]
+ Rustc(&'a Sysroot),
+ Cargo(&'a Sysroot, &'a ManifestPath),
+}
+
+pub(super) fn get(
+ config: TargetTipleConfig<'_>,
+ target: Option<&str>,
+ extra_env: &FxHashMap<String, String>,
+) -> anyhow::Result<Vec<String>> {
+ if let Some(target) = target {
+ return Ok(vec![target.to_owned()]);
+ }
+
+ let sysroot = match config {
+ TargetTipleConfig::Cargo(sysroot, cargo_toml) => {
+ match cargo_config_build_target(cargo_toml, extra_env, sysroot) {
+ Ok(it) => return Ok(it),
+ Err(e) => {
+ tracing::warn!("failed to run `cargo rustc --print cfg`, falling back to invoking rustc directly: {e}");
+ sysroot
+ }
+ }
+ }
+ TargetTipleConfig::Rustc(sysroot) => sysroot,
+ };
+ rustc_discover_host_triple(extra_env, sysroot).map(|it| vec![it])
+}
+
+fn rustc_discover_host_triple(
+ extra_env: &FxHashMap<String, String>,
+ sysroot: &Sysroot,
+) -> anyhow::Result<String> {
+ let mut rustc = sysroot.tool(Tool::Rustc);
+ rustc.envs(extra_env);
+ rustc.arg("-vV");
+ tracing::debug!("Discovering host platform by {:?}", rustc);
+ let stdout = utf8_stdout(rustc).context("Failed to discover host platform")?;
+ let field = "host: ";
+ let target = stdout.lines().find_map(|l| l.strip_prefix(field));
+ if let Some(target) = target {
+ Ok(target.to_owned())
+ } else {
+ // If we fail to resolve the host platform, it's not the end of the world.
+ Err(anyhow::format_err!("rustc -vV did not report host platform, got:\n{}", stdout))
+ }
+}
+
+fn cargo_config_build_target(
+ cargo_toml: &ManifestPath,
+ extra_env: &FxHashMap<String, String>,
+ sysroot: &Sysroot,
+) -> anyhow::Result<Vec<String>> {
+ let mut cargo_config = sysroot.tool(Tool::Cargo);
+ cargo_config.envs(extra_env);
+ cargo_config
+ .current_dir(cargo_toml.parent())
+ .args(["-Z", "unstable-options", "config", "get", "build.target"])
+ .env("RUSTC_BOOTSTRAP", "1");
+ // if successful we receive `build.target = "target-triple"`
+ // or `build.target = ["<target 1>", ..]`
+ tracing::debug!("Discovering cargo config target by {:?}", cargo_config);
+ utf8_stdout(cargo_config).and_then(parse_output_cargo_config_build_target)
+}
+
+fn parse_output_cargo_config_build_target(stdout: String) -> anyhow::Result<Vec<String>> {
+ let trimmed = stdout.trim_start_matches("build.target = ").trim_matches('"');
+
+ if !trimmed.starts_with('[') {
+ return Ok([trimmed.to_owned()].to_vec());
+ }
+
+ serde_json::from_str(trimmed).context("Failed to parse `build.target` as an array of target")
+}
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index f3cf2d83ea..9fc2d6116a 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -117,7 +117,7 @@ fn get_fake_sysroot() -> Sysroot {
// fake sysroot, so we give them both the same path:
let sysroot_dir = AbsPathBuf::assert(sysroot_path);
let sysroot_src_dir = sysroot_dir.clone();
- Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), SysrootQueryMetadata::CargoMetadata)
+ Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir), &SysrootQueryMetadata::default())
}
fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
@@ -232,7 +232,7 @@ fn smoke_test_real_sysroot_cargo() {
let sysroot = Sysroot::discover(
AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))),
&Default::default(),
- SysrootQueryMetadata::CargoMetadata,
+ &SysrootQueryMetadata::default(),
);
assert!(matches!(sysroot.mode(), SysrootMode::Workspace(_)));
let project_workspace = ProjectWorkspace {
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 71ddee3091..d747a8086b 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -2,7 +2,7 @@
//! metadata` or `rust-project.json`) into representation stored in the salsa
//! database -- `CrateGraph`.
-use std::{collections::VecDeque, fmt, fs, iter, sync};
+use std::{collections::VecDeque, fmt, fs, iter, ops::Deref, sync};
use anyhow::Context;
use base_db::{
@@ -22,12 +22,13 @@ use triomphe::Arc;
use crate::{
build_dependencies::BuildScriptOutput,
- cargo_workspace::{DepKind, PackageData, RustLibSource},
+ cargo_workspace::{CargoMetadataConfig, DepKind, PackageData, RustLibSource},
env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
project_json::{Crate, CrateArrayIdx},
rustc_cfg::{self, RustcCfgConfig},
sysroot::{SysrootCrate, SysrootMode},
target_data_layout::{self, RustcDataLayoutConfig},
+ target_triple::{self, TargetTipleConfig},
utf8_stdout, CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath,
Package, ProjectJson, ProjectManifest, Sysroot, TargetData, TargetKind, WorkspaceBuildScripts,
};
@@ -220,28 +221,31 @@ impl ProjectWorkspace {
ProjectWorkspace::load_detached_file(rust_file, config)?
}
ProjectManifest::CargoToml(cargo_toml) => {
+ // FIXME: Split sysroot discovery from sysroot loading, as to load the sysroot we
+ // want to pass the analysis target, but to discover the target we need to know the
+ // sysroot location so we know which cargo to use
let sysroot = match (&config.sysroot, &config.sysroot_src) {
(Some(RustLibSource::Discover), None) => Sysroot::discover(
cargo_toml.parent(),
&config.extra_env,
- config.sysroot_query_metadata,
+ &config.sysroot_query_metadata,
),
(Some(RustLibSource::Discover), Some(sysroot_src)) => {
Sysroot::discover_with_src_override(
cargo_toml.parent(),
&config.extra_env,
sysroot_src.clone(),
- config.sysroot_query_metadata,
+ &config.sysroot_query_metadata,
)
}
(Some(RustLibSource::Path(path)), None) => Sysroot::discover_sysroot_src_dir(
path.clone(),
- config.sysroot_query_metadata,
+ &config.sysroot_query_metadata,
),
(Some(RustLibSource::Path(sysroot)), Some(sysroot_src)) => Sysroot::load(
Some(sysroot.clone()),
Some(sysroot_src.clone()),
- config.sysroot_query_metadata,
+ &config.sysroot_query_metadata,
),
(None, _) => Sysroot::empty(),
};
@@ -257,15 +261,22 @@ impl ProjectWorkspace {
}
None => Err(None),
};
-
+ let targets = target_triple::get(
+ TargetTipleConfig::Cargo(&sysroot, cargo_toml),
+ config.target.as_deref(),
+ &config.extra_env,
+ )
+ .unwrap_or_default();
let rustc = rustc_dir.and_then(|rustc_dir| {
info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
match CargoWorkspace::fetch_metadata(
&rustc_dir,
cargo_toml.parent(),
- &CargoConfig {
+ &CargoMetadataConfig {
features: crate::CargoFeatures::default(),
- ..config.clone()
+ targets: targets.clone(),
+ extra_args: config.extra_args.clone(),
+ extra_env: config.extra_env.clone(),
},
&sysroot,
false,
@@ -301,7 +312,7 @@ impl ProjectWorkspace {
"cargo ",
)?;
let rustc_cfg = rustc_cfg::get(
- config.target.as_deref(),
+ targets.first().map(Deref::deref),
&config.extra_env,
RustcCfgConfig::Cargo(&sysroot, cargo_toml),
);
@@ -309,7 +320,7 @@ impl ProjectWorkspace {
let cfg_overrides = config.cfg_overrides.clone();
let data_layout = target_data_layout::get(
RustcDataLayoutConfig::Cargo(&sysroot, cargo_toml),
- config.target.as_deref(),
+ targets.first().map(Deref::deref),
&config.extra_env,
);
if let Err(e) = &data_layout {
@@ -319,7 +330,12 @@ impl ProjectWorkspace {
let (meta, error) = CargoWorkspace::fetch_metadata(
cargo_toml,
cargo_toml.parent(),
- config,
+ &CargoMetadataConfig {
+ features: config.features.clone(),
+ targets,
+ extra_args: config.extra_args.clone(),
+ extra_env: config.extra_env.clone(),
+ },
&sysroot,
false,
progress,
@@ -360,7 +376,7 @@ impl ProjectWorkspace {
let sysroot = Sysroot::load(
project_json.sysroot.clone(),
project_json.sysroot_src.clone(),
- config.sysroot_query_metadata,
+ &config.sysroot_query_metadata,
);
let cfg_config = RustcCfgConfig::Rustc(&sysroot);
let data_layout_config = RustcDataLayoutConfig::Rustc(&sysroot);
@@ -398,10 +414,10 @@ impl ProjectWorkspace {
let dir = detached_file.parent();
let sysroot = match &config.sysroot {
Some(RustLibSource::Path(path)) => {
- Sysroot::discover_sysroot_src_dir(path.clone(), config.sysroot_query_metadata)
+ Sysroot::discover_sysroot_src_dir(path.clone(), &config.sysroot_query_metadata)
}
Some(RustLibSource::Discover) => {
- Sysroot::discover(dir, &config.extra_env, config.sysroot_query_metadata)
+ Sysroot::discover(dir, &config.extra_env, &config.sysroot_query_metadata)
}
None => Sysroot::empty(),
};
@@ -415,6 +431,12 @@ impl ProjectWorkspace {
}
};
+ let targets = target_triple::get(
+ TargetTipleConfig::Cargo(&sysroot, detached_file),
+ config.target.as_deref(),
+ &config.extra_env,
+ )
+ .unwrap_or_default();
let rustc_cfg = rustc_cfg::get(None, &config.extra_env, RustcCfgConfig::Rustc(&sysroot));
let data_layout = target_data_layout::get(
RustcDataLayoutConfig::Rustc(&sysroot),
@@ -422,16 +444,27 @@ impl ProjectWorkspace {
&config.extra_env,
);
- let cargo_script =
- CargoWorkspace::fetch_metadata(detached_file, dir, config, &sysroot, false, &|_| ())
- .ok()
- .map(|(ws, error)| {
- (
- CargoWorkspace::new(ws, detached_file.clone()),
- WorkspaceBuildScripts::default(),
- error.map(Arc::new),
- )
- });
+ let cargo_script = CargoWorkspace::fetch_metadata(
+ detached_file,
+ dir,
+ &CargoMetadataConfig {
+ features: config.features.clone(),
+ targets,
+ extra_args: config.extra_args.clone(),
+ extra_env: config.extra_env.clone(),
+ },
+ &sysroot,
+ false,
+ &|_| (),
+ )
+ .ok()
+ .map(|(ws, error)| {
+ (
+ CargoWorkspace::new(ws, detached_file.clone()),
+ WorkspaceBuildScripts::default(),
+ error.map(Arc::new),
+ )
+ });
let cargo_config_extra_env = cargo_config_env(detached_file, &config.extra_env, &sysroot);
Ok(ProjectWorkspace {
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index caa42dd62c..1a9cdef256 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -10,7 +10,7 @@ extern crate rustc_driver as _;
mod rustc_wrapper;
-use std::{env, fs, path::PathBuf, process::ExitCode, sync::Arc, thread::sleep};
+use std::{env, fs, path::PathBuf, process::ExitCode, sync::Arc};
use anyhow::Context;
use lsp_server::Connection;
@@ -100,7 +100,7 @@ fn wait_for_debugger() {
// SAFETY: WinAPI generated code that is defensively marked `unsafe` but
// in practice can not be used in an unsafe way.
while unsafe { IsDebuggerPresent() } == 0 {
- sleep(std::time::Duration::from_millis(100));
+ std::thread::sleep(std::time::Duration::from_millis(100));
}
}
#[cfg(not(target_os = "windows"))]
@@ -109,7 +109,7 @@ fn wait_for_debugger() {
let mut d = 4;
while d == 4 {
d = 4;
- sleep(std::time::Duration::from_millis(100));
+ std::thread::sleep(std::time::Duration::from_millis(100));
}
}
}
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 66cd2e424e..9b428871c4 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -33,7 +33,10 @@ use itertools::Itertools;
use load_cargo::{load_workspace, LoadCargoConfig, ProcMacroServerChoice};
use oorandom::Rand32;
use profile::{Bytes, StopWatch};
-use project_model::{CargoConfig, CfgOverrides, ProjectManifest, ProjectWorkspace, RustLibSource};
+use project_model::{
+ CargoConfig, CargoMetadataConfig, CfgOverrides, ProjectManifest, ProjectWorkspace,
+ RustLibSource,
+};
use rayon::prelude::*;
use rustc_hash::{FxHashMap, FxHashSet};
use syntax::{AstNode, SyntaxNode};
@@ -68,7 +71,9 @@ impl flags::AnalysisStats {
},
sysroot_query_metadata: match self.no_query_sysroot_metadata {
true => project_model::SysrootQueryMetadata::None,
- false => project_model::SysrootQueryMetadata::CargoMetadata,
+ false => project_model::SysrootQueryMetadata::CargoMetadata(
+ CargoMetadataConfig::default(),
+ ),
},
all_targets: true,
set_test: !self.no_test,
diff --git a/crates/rust-analyzer/src/cli/rustc_tests.rs b/crates/rust-analyzer/src/cli/rustc_tests.rs
index 6483afc85b..db792ade57 100644
--- a/crates/rust-analyzer/src/cli/rustc_tests.rs
+++ b/crates/rust-analyzer/src/cli/rustc_tests.rs
@@ -77,7 +77,7 @@ impl Tester {
let sysroot = Sysroot::discover(
tmp_file.parent().unwrap(),
&cargo_config.extra_env,
- SysrootQueryMetadata::CargoMetadata,
+ &SysrootQueryMetadata::CargoMetadata(Default::default()),
);
let data_layout = target_data_layout::get(
RustcDataLayoutConfig::Rustc(&sysroot),
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 773db8ad25..c182952c73 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -21,8 +21,8 @@ use ide_db::{
use itertools::Itertools;
use paths::{Utf8Path, Utf8PathBuf};
use project_model::{
- CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectJsonFromCommand,
- ProjectManifest, RustLibSource,
+ CargoConfig, CargoFeatures, CargoMetadataConfig, ProjectJson, ProjectJsonData,
+ ProjectJsonFromCommand, ProjectManifest, RustLibSource,
};
use rustc_hash::{FxHashMap, FxHashSet};
use semver::Version;
@@ -1881,7 +1881,12 @@ impl Config {
sysroot,
sysroot_query_metadata: match self.cargo_sysrootQueryMetadata(None) {
SysrootQueryMetadata::CargoMetadata => {
- project_model::SysrootQueryMetadata::CargoMetadata
+ project_model::SysrootQueryMetadata::CargoMetadata(CargoMetadataConfig {
+ features: Default::default(),
+ targets: self.cargo_target(source_root).clone().into_iter().collect(),
+ extra_args: Default::default(),
+ extra_env: Default::default(),
+ })
}
SysrootQueryMetadata::None => project_model::SysrootQueryMetadata::None,
},