diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs index 78f2c16517dc3..2649d88ac2c29 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs @@ -18,7 +18,7 @@ mod closure; fn current_machine_data_layout() -> String { project_model::toolchain_info::target_data_layout::get( - QueryConfig::Rustc(&Sysroot::empty()), + QueryConfig::Rustc(&Sysroot::empty(), &std::env::current_dir().unwrap()), None, &FxHashMap::default(), ) diff --git a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info.rs b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info.rs index ad6f3fae8e667..6c8152262c3a2 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info.rs @@ -2,11 +2,14 @@ pub mod rustc_cfg; pub mod target_data_layout; pub mod target_triple; +use std::path::Path; + use crate::{ManifestPath, Sysroot}; +#[derive(Copy, Clone)] pub enum QueryConfig<'a> { /// Directly invoke `rustc` to query the desired information. - Rustc(&'a Sysroot), + Rustc(&'a Sysroot, &'a Path), /// Attempt to use cargo to query the desired information, honoring cargo configurations. /// If this fails, falls back to invoking `rustc` directly. Cargo(&'a Sysroot, &'a ManifestPath), diff --git a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/rustc_cfg.rs b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/rustc_cfg.rs index 527118df4f64e..12e674a6c4f07 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/rustc_cfg.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/rustc_cfg.rs @@ -43,7 +43,7 @@ fn rustc_print_cfg( config: QueryConfig<'_>, ) -> anyhow::Result { const RUSTC_ARGS: [&str; 3] = ["--print", "cfg", "-O"]; - let sysroot = match config { + let (sysroot, current_dir) = match config { QueryConfig::Cargo(sysroot, cargo_toml) => { let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent()); cmd.envs(extra_env); @@ -60,14 +60,14 @@ fn rustc_print_cfg( %e, "failed to run `{cmd:?}`, falling back to invoking rustc directly" ); - sysroot + (sysroot, cargo_toml.parent().as_ref()) } } } - QueryConfig::Rustc(sysroot) => sysroot, + QueryConfig::Rustc(sysroot, current_dir) => (sysroot, current_dir), }; - let mut cmd = sysroot.tool(Tool::Rustc, &std::env::current_dir()?); + let mut cmd = sysroot.tool(Tool::Rustc, current_dir); cmd.envs(extra_env); cmd.args(RUSTC_ARGS); if let Some(target) = target { diff --git a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data_layout.rs b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data_layout.rs index 17af27a222d9a..9986c661311e0 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data_layout.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data_layout.rs @@ -19,7 +19,7 @@ pub fn get( anyhow::format_err!("could not parse target-spec-json from command output") }) }; - let sysroot = match config { + let (sysroot, current_dir) = match config { QueryConfig::Cargo(sysroot, cargo_toml) => { let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent()); cmd.envs(extra_env); @@ -36,14 +36,14 @@ pub fn get( Ok(output) => return process(output), Err(e) => { tracing::warn!(%e, "failed to run `{cmd:?}`, falling back to invoking rustc directly"); - sysroot + (sysroot, cargo_toml.parent().as_ref()) } } } - QueryConfig::Rustc(sysroot) => sysroot, + QueryConfig::Rustc(sysroot, current_dir) => (sysroot, current_dir), }; - let mut cmd = Sysroot::tool(sysroot, Tool::Rustc, &std::env::current_dir()?); + let mut cmd = Sysroot::tool(sysroot, Tool::Rustc, current_dir); cmd.envs(extra_env) .env("RUSTC_BOOTSTRAP", "1") .args(["-Z", "unstable-options"]) diff --git a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_triple.rs b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_triple.rs index 6b68cc67655d6..2d0d4a7c50c26 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_triple.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_triple.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use anyhow::Context; use rustc_hash::FxHashMap; use toolchain::Tool; @@ -16,23 +18,24 @@ pub fn get( return Ok(vec![target.to_owned()]); } - let sysroot = match config { + let (sysroot, current_dir) = match config { QueryConfig::Cargo(sysroot, cargo_toml) => { match cargo_config_build_target(cargo_toml, extra_env, sysroot) { Some(it) => return Ok(it), - None => sysroot, + None => (sysroot, cargo_toml.parent().as_ref()), } } - QueryConfig::Rustc(sysroot) => sysroot, + QueryConfig::Rustc(sysroot, current_dir) => (sysroot, current_dir), }; - rustc_discover_host_triple(extra_env, sysroot).map(|it| vec![it]) + rustc_discover_host_triple(extra_env, sysroot, current_dir).map(|it| vec![it]) } fn rustc_discover_host_triple( extra_env: &FxHashMap, sysroot: &Sysroot, + current_dir: &Path, ) -> anyhow::Result { - let mut cmd = sysroot.tool(Tool::Rustc, &std::env::current_dir()?); + let mut cmd = sysroot.tool(Tool::Rustc, current_dir); cmd.envs(extra_env); cmd.arg("-vV"); let stdout = utf8_stdout(&mut cmd) diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 8fbf7c05c4d11..233f94203e79c 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -373,8 +373,7 @@ impl ProjectWorkspace { project_json.sysroot_src.clone(), &config.sysroot_query_metadata, ); - let cfg_config = QueryConfig::Rustc(&sysroot); - let data_layout_config = QueryConfig::Rustc(&sysroot); + let query_config = QueryConfig::Rustc(&sysroot, project_json.path().as_ref()); let toolchain = match get_toolchain_version( project_json.path(), &sysroot, @@ -390,8 +389,8 @@ impl ProjectWorkspace { }; let target = config.target.as_deref(); - let rustc_cfg = rustc_cfg::get(cfg_config, target, &config.extra_env); - let data_layout = target_data_layout::get(data_layout_config, target, &config.extra_env); + let rustc_cfg = rustc_cfg::get(query_config, target, &config.extra_env); + let data_layout = target_data_layout::get(query_config, target, &config.extra_env); ProjectWorkspace { kind: ProjectWorkspaceKind::Json(project_json), sysroot, @@ -432,9 +431,9 @@ impl ProjectWorkspace { &config.extra_env, ) .unwrap_or_default(); - let rustc_cfg = rustc_cfg::get(QueryConfig::Rustc(&sysroot), None, &config.extra_env); - let data_layout = - target_data_layout::get(QueryConfig::Rustc(&sysroot), None, &config.extra_env); + let query_config = QueryConfig::Rustc(&sysroot, dir.as_ref()); + let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env); + let data_layout = target_data_layout::get(query_config, None, &config.extra_env); let cargo_script = CargoWorkspace::fetch_metadata( detached_file, @@ -946,7 +945,11 @@ fn project_json_to_crate_graph( let target_cfgs = match target.as_deref() { Some(target) => cfg_cache.entry(target).or_insert_with(|| { - rustc_cfg::get(QueryConfig::Rustc(sysroot), Some(target), extra_env) + rustc_cfg::get( + QueryConfig::Rustc(sysroot, project.project_root().as_ref()), + Some(target), + extra_env, + ) }), None => &rustc_cfg, }; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index 4da916080cafe..dabc71b1b9923 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -79,8 +79,11 @@ impl Tester { &cargo_config.extra_env, &SysrootQueryMetadata::CargoMetadata(Default::default()), ); - let data_layout = - target_data_layout::get(QueryConfig::Rustc(&sysroot), None, &cargo_config.extra_env); + let data_layout = target_data_layout::get( + QueryConfig::Rustc(&sysroot, tmp_file.parent().unwrap().as_ref()), + None, + &cargo_config.extra_env, + ); let workspace = ProjectWorkspace { kind: ProjectWorkspaceKind::DetachedFile {