From 4265f4aba3d8d7f3e8caadbd50f1002523f47348 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 24 Dec 2024 17:21:46 +0100 Subject: [PATCH] Cleanup target fetching for cargo metadata --- crates/project-model/src/cargo_workspace.rs | 105 +++--------------- crates/project-model/src/lib.rs | 16 ++- crates/project-model/src/sysroot.rs | 31 ++++-- crates/project-model/src/target_triple.rs | 86 ++++++++++++++ crates/project-model/src/tests.rs | 4 +- crates/project-model/src/workspace.rs | 83 +++++++++----- crates/rust-analyzer/src/bin/main.rs | 6 +- .../rust-analyzer/src/cli/analysis_stats.rs | 9 +- crates/rust-analyzer/src/cli/rustc_tests.rs | 2 +- crates/rust-analyzer/src/config.rs | 11 +- 10 files changed, 213 insertions(+), 140 deletions(-) create mode 100644 crates/project-model/src/target_triple.rs diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs index ba4946bf0b99..836879c75bff 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, + /// Extra args to pass to the cargo command. + pub extra_args: Vec, + /// Extra env vars to set when invoking the cargo command + pub extra_env: FxHashMap, +} + // 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)> { - 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 { - 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, - sysroot: &Sysroot, -) -> Option { - 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, - sysroot: &Sysroot, -) -> Vec { - 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 = ["", ..]` - 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 { - 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 da8afc5d3a18..9a024f6b962e 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 { 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 8426e689a64d..d8186a23f76b 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, - 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, 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, sysroot_src_dir: Option, - 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>, sysroot_src_dir: Option>, - 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>, sysroot_src_dir: Option>, - 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, sysroot_src_dir: &AbsPathBuf, + cargo_config: &CargoMetadataConfig, ) -> Option { 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 000000000000..a8074f07d224 --- /dev/null +++ b/crates/project-model/src/target_triple.rs @@ -0,0 +1,86 @@ +use anyhow::Context; +use rustc_hash::FxHashMap; +use toolchain::Tool; + +use crate::{utf8_stdout, ManifestPath, Sysroot}; + +/// Determines how `rustc --print target-spec-json` is discovered and invoked. +pub(super) enum TargetTipleConfig<'a> { + /// Use `rustc --print target-spec-json`, either from with the binary from the sysroot or by discovering via + /// [`toolchain::rustc`]. + #[expect(dead_code)] + Rustc(&'a Sysroot), + /// Use `cargo --print target-spec-json`, either from with the binary from the sysroot or by discovering via + /// [`toolchain::cargo`]. + Cargo(&'a Sysroot, &'a ManifestPath), +} + +pub(super) fn get( + config: TargetTipleConfig<'_>, + target: Option<&str>, + extra_env: &FxHashMap, +) -> anyhow::Result> { + 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, + sysroot: &Sysroot, +) -> anyhow::Result { + 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, + sysroot: &Sysroot, +) -> anyhow::Result> { + 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 = ["", ..]` + 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> { + 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 f3cf2d83eaca..9fc2d6116a46 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 71ddee309100..d747a8086b46 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 caa42dd62cd2..1a9cdef256d2 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 66cd2e424e38..9b428871c408 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 6483afc85b21..db792ade574d 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 b06117f73835..4160dd16becf 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; @@ -1862,7 +1862,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, },