about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2025-01-07 12:34:22 +0100
committerLukas Wirth <lukastw97@gmail.com>2025-01-07 14:30:46 +0100
commitd28a0b8fcd4e80c9cbfd6caf7753e7909bcaf5b4 (patch)
treec6b384f81f5f25daad9e01ee5d90f3513aaf9e09
parent05770f25994b4ac6395c34ad3ee7e6ae13bebee0 (diff)
downloadrust-d28a0b8fcd4e80c9cbfd6caf7753e7909bcaf5b4.tar.gz
rust-d28a0b8fcd4e80c9cbfd6caf7753e7909bcaf5b4.zip
Align toolchain version fetching with other toolchain info querying
Fix --target flag argument order in rustc_cfg fetching
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/lib.rs1
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/toolchain_info/rustc_cfg.rs5
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/toolchain_info/version.rs32
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs165
4 files changed, 93 insertions, 110 deletions
diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs
index dec4f1456ba..fc1fd7b877f 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs
@@ -20,6 +20,7 @@ pub mod toolchain_info {
     pub mod rustc_cfg;
     pub mod target_data_layout;
     pub mod target_tuple;
+    pub mod version;
 
     use std::path::Path;
 
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 b1e8c3376a1..791d1773d73 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
@@ -66,12 +66,11 @@ fn rustc_print_cfg(
         QueryConfig::Cargo(sysroot, cargo_toml) => {
             let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent());
             cmd.envs(extra_env);
-            cmd.env("RUSTC_BOOTSTRAP", "1");
-            cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS);
-            cmd.args(["--", "-O"]);
+            cmd.args(["rustc"]).args(RUSTC_ARGS);
             if let Some(target) = target {
                 cmd.args(["--target", target]);
             }
+            cmd.args(["--", "-O"]);
 
             match utf8_stdout(&mut cmd) {
                 Ok(it) => return Ok(it),
diff --git a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/version.rs b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/version.rs
new file mode 100644
index 00000000000..a873944dd8a
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/version.rs
@@ -0,0 +1,32 @@
+//! Get the version string of the toolchain.
+
+use anyhow::Context;
+use rustc_hash::FxHashMap;
+use semver::Version;
+use toolchain::Tool;
+
+use crate::{toolchain_info::QueryConfig, utf8_stdout};
+
+pub(crate) fn get(
+    config: QueryConfig<'_>,
+    extra_env: &FxHashMap<String, String>,
+) -> Result<Option<Version>, anyhow::Error> {
+    let (mut cmd, prefix) = match config {
+        QueryConfig::Cargo(sysroot, cargo_toml) => {
+            (sysroot.tool(Tool::Cargo, cargo_toml.parent()), "cargo ")
+        }
+        QueryConfig::Rustc(sysroot, current_dir) => {
+            (sysroot.tool(Tool::Rustc, current_dir), "rustc ")
+        }
+    };
+    cmd.envs(extra_env);
+    cmd.arg("--version");
+    let out = utf8_stdout(&mut cmd).with_context(|| format!("Failed to query rust toolchain version via `{cmd:?}`, is your toolchain setup correctly?"))?;
+
+    let version =
+        out.strip_prefix(prefix).and_then(|it| Version::parse(it.split_whitespace().next()?).ok());
+    if version.is_none() {
+        tracing::warn!("Failed to parse `{cmd:?}` output `{out}` as a semver version");
+    }
+    anyhow::Ok(version)
+}
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 905e83b27d1..95f8bb9950a 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -16,7 +16,6 @@ use paths::{AbsPath, AbsPathBuf};
 use rustc_hash::FxHashMap;
 use semver::Version;
 use span::{Edition, FileId};
-use toolchain::Tool;
 use tracing::instrument;
 use triomphe::Arc;
 
@@ -26,10 +25,10 @@ use crate::{
     env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
     project_json::{Crate, CrateArrayIdx},
     sysroot::{SysrootCrate, SysrootWorkspace},
-    toolchain_info::{rustc_cfg, target_data_layout, target_tuple, QueryConfig},
-    utf8_stdout, CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath,
-    Package, ProjectJson, ProjectManifest, Sysroot, SysrootSourceWorkspaceConfig, TargetData,
-    TargetKind, WorkspaceBuildScripts,
+    toolchain_info::{rustc_cfg, target_data_layout, target_tuple, version, QueryConfig},
+    CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath, Package,
+    ProjectJson, ProjectManifest, Sysroot, SysrootSourceWorkspaceConfig, TargetData, TargetKind,
+    WorkspaceBuildScripts,
 };
 use tracing::{debug, error, info};
 
@@ -151,27 +150,6 @@ impl fmt::Debug for ProjectWorkspace {
     }
 }
 
-fn get_toolchain_version(
-    current_dir: &AbsPath,
-    sysroot: &Sysroot,
-    tool: Tool,
-    extra_env: &FxHashMap<String, String>,
-    prefix: &str,
-) -> Result<Option<Version>, anyhow::Error> {
-    let cargo_version = utf8_stdout(&mut {
-        let mut cmd = Sysroot::tool(sysroot, tool, current_dir);
-        cmd.envs(extra_env);
-        cmd.arg("--version");
-        cmd
-    })
-    .with_context(|| format!("Failed to query rust toolchain version at {current_dir}, is your toolchain setup correctly?"))?;
-    anyhow::Ok(
-        cargo_version
-            .get(prefix.len()..)
-            .and_then(|it| Version::parse(it.split_whitespace().next()?).ok()),
-    )
-}
-
 impl ProjectWorkspace {
     pub fn load(
         manifest: ProjectManifest,
@@ -242,16 +220,52 @@ impl ProjectWorkspace {
                 .ok_or_else(|| Some("Failed to discover rustc source for sysroot.".to_owned())),
             None => Err(None),
         };
-        let targets = target_tuple::get(
-            QueryConfig::Cargo(&sysroot, cargo_toml),
-            config.target.as_deref(),
+
+        tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot");
+        let toolchain_config = QueryConfig::Cargo(&sysroot, cargo_toml);
+        let targets =
+            target_tuple::get(toolchain_config, config.target.as_deref(), &config.extra_env)
+                .unwrap_or_default();
+        let toolchain = version::get(toolchain_config, &config.extra_env)
+            .inspect_err(|e| {
+                tracing::error!(%e,
+                    "failed fetching toolchain version for {cargo_toml:?} workspace"
+                )
+            })
+            .ok()
+            .flatten();
+        let rustc_cfg =
+            rustc_cfg::get(toolchain_config, targets.first().map(Deref::deref), &config.extra_env);
+        let cfg_overrides = config.cfg_overrides.clone();
+        let data_layout = target_data_layout::get(
+            toolchain_config,
+            targets.first().map(Deref::deref),
             &config.extra_env,
+        );
+        if let Err(e) = &data_layout {
+            tracing::error!(%e, "failed fetching data layout for {cargo_toml:?} workspace");
+        }
+
+        let (meta, error) = CargoWorkspace::fetch_metadata(
+            cargo_toml,
+            cargo_toml.parent(),
+            &CargoMetadataConfig {
+                features: config.features.clone(),
+                targets: targets.clone(),
+                extra_args: config.extra_args.clone(),
+                extra_env: config.extra_env.clone(),
+            },
+            &sysroot,
+            false,
+            progress,
         )
-        .unwrap_or_default();
-        sysroot.load_workspace(&SysrootSourceWorkspaceConfig::CargoMetadata(
-            sysroot_metadata_config(&config.extra_env, &targets),
-        ));
-        tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot");
+        .with_context(|| {
+            format!(
+                "Failed to read Cargo metadata from Cargo.toml file {cargo_toml}, {toolchain:?}",
+            )
+        })?;
+        let cargo_config_extra_env = cargo_config_env(cargo_toml, &config.extra_env, &sysroot);
+        let cargo = CargoWorkspace::new(meta, cargo_toml.clone(), cargo_config_extra_env);
         let rustc = rustc_dir.and_then(|rustc_dir| {
             info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
             match CargoWorkspace::fetch_metadata(
@@ -288,47 +302,9 @@ impl ProjectWorkspace {
                 }
             }
         });
-        let toolchain = get_toolchain_version(
-            cargo_toml.parent(),
-            &sysroot,
-            Tool::Cargo,
-            &config.extra_env,
-            "cargo ",
-        )?;
-        let rustc_cfg = rustc_cfg::get(
-            QueryConfig::Cargo(&sysroot, cargo_toml),
-            targets.first().map(Deref::deref),
-            &config.extra_env,
-        );
-        let cfg_overrides = config.cfg_overrides.clone();
-        let data_layout = target_data_layout::get(
-            QueryConfig::Cargo(&sysroot, cargo_toml),
-            targets.first().map(Deref::deref),
-            &config.extra_env,
-        );
-        if let Err(e) = &data_layout {
-            tracing::error!(%e, "failed fetching data layout for {cargo_toml:?} workspace");
-        }
-        let (meta, error) = CargoWorkspace::fetch_metadata(
-            cargo_toml,
-            cargo_toml.parent(),
-            &CargoMetadataConfig {
-                features: config.features.clone(),
-                targets,
-                extra_args: config.extra_args.clone(),
-                extra_env: config.extra_env.clone(),
-            },
-            &sysroot,
-            false,
-            progress,
-        )
-        .with_context(|| {
-            format!(
-                "Failed to read Cargo metadata from Cargo.toml file {cargo_toml}, {toolchain:?}",
-            )
-        })?;
-        let cargo_config_extra_env = cargo_config_env(cargo_toml, &config.extra_env, &sysroot);
-        let cargo = CargoWorkspace::new(meta, cargo_toml.clone(), cargo_config_extra_env);
+        sysroot.load_workspace(&SysrootSourceWorkspaceConfig::CargoMetadata(
+            sysroot_metadata_config(&config.extra_env, &targets),
+        ));
         Ok(ProjectWorkspace {
             kind: ProjectWorkspaceKind::Cargo {
                 cargo,
@@ -350,19 +326,7 @@ impl ProjectWorkspace {
             Sysroot::new(project_json.sysroot.clone(), project_json.sysroot_src.clone());
         sysroot.load_workspace(&SysrootSourceWorkspaceConfig::Stitched);
         let query_config = QueryConfig::Rustc(&sysroot, project_json.path().as_ref());
-        let toolchain = match get_toolchain_version(
-            project_json.path(),
-            &sysroot,
-            Tool::Rustc,
-            &config.extra_env,
-            "rustc ",
-        ) {
-            Ok(it) => it,
-            Err(e) => {
-                tracing::error!("{e}");
-                None
-            }
-        };
+        let toolchain = version::get(query_config, &config.extra_env).ok().flatten();
 
         let target = config.target.as_deref();
         let rustc_cfg = rustc_cfg::get(query_config, target, &config.extra_env);
@@ -388,28 +352,15 @@ impl ProjectWorkspace {
             None => Sysroot::empty(),
         };
 
-        let toolchain =
-            match get_toolchain_version(dir, &sysroot, Tool::Rustc, &config.extra_env, "rustc ") {
-                Ok(it) => it,
-                Err(e) => {
-                    tracing::error!("{e}");
-                    None
-                }
-            };
-
-        let targets = target_tuple::get(
-            QueryConfig::Cargo(&sysroot, detached_file),
-            config.target.as_deref(),
-            &config.extra_env,
-        )
-        .unwrap_or_default();
-
+        let query_config = QueryConfig::Cargo(&sysroot, detached_file);
+        let toolchain = version::get(query_config, &config.extra_env).ok().flatten();
+        let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env)
+            .unwrap_or_default();
+        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);
         sysroot.load_workspace(&SysrootSourceWorkspaceConfig::CargoMetadata(
             sysroot_metadata_config(&config.extra_env, &targets),
         ));
-        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,