mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-11 20:58:54 +00:00
Align toolchain version fetching with other toolchain info querying
Fix --target flag argument order in rustc_cfg fetching
This commit is contained in:
parent
2ac803ec71
commit
b8a0488740
4 changed files with 94 additions and 111 deletions
|
@ -20,6 +20,7 @@ pub mod toolchain_info {
|
||||||
pub mod rustc_cfg;
|
pub mod rustc_cfg;
|
||||||
pub mod target_data_layout;
|
pub mod target_data_layout;
|
||||||
pub mod target_tuple;
|
pub mod target_tuple;
|
||||||
|
pub mod version;
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
|
|
@ -66,12 +66,11 @@ fn rustc_print_cfg(
|
||||||
QueryConfig::Cargo(sysroot, cargo_toml) => {
|
QueryConfig::Cargo(sysroot, cargo_toml) => {
|
||||||
let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent());
|
let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent());
|
||||||
cmd.envs(extra_env);
|
cmd.envs(extra_env);
|
||||||
cmd.env("RUSTC_BOOTSTRAP", "1");
|
cmd.args(["rustc"]).args(RUSTC_ARGS);
|
||||||
cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS);
|
|
||||||
cmd.args(["--", "-O"]);
|
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
cmd.args(["--target", target]);
|
cmd.args(["--target", target]);
|
||||||
}
|
}
|
||||||
|
cmd.args(["--", "-O"]);
|
||||||
|
|
||||||
match utf8_stdout(&mut cmd) {
|
match utf8_stdout(&mut cmd) {
|
||||||
Ok(it) => return Ok(it),
|
Ok(it) => return Ok(it),
|
||||||
|
|
32
crates/project-model/src/toolchain_info/version.rs
Normal file
32
crates/project-model/src/toolchain_info/version.rs
Normal file
|
@ -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)
|
||||||
|
}
|
|
@ -16,7 +16,6 @@ use paths::{AbsPath, AbsPathBuf};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use span::{Edition, FileId};
|
use span::{Edition, FileId};
|
||||||
use toolchain::Tool;
|
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
|
@ -26,10 +25,10 @@ use crate::{
|
||||||
env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
|
env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
|
||||||
project_json::{Crate, CrateArrayIdx},
|
project_json::{Crate, CrateArrayIdx},
|
||||||
sysroot::{SysrootCrate, SysrootWorkspace},
|
sysroot::{SysrootCrate, SysrootWorkspace},
|
||||||
toolchain_info::{rustc_cfg, target_data_layout, target_tuple, QueryConfig},
|
toolchain_info::{rustc_cfg, target_data_layout, target_tuple, version, QueryConfig},
|
||||||
utf8_stdout, CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath,
|
CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath, Package,
|
||||||
Package, ProjectJson, ProjectManifest, Sysroot, SysrootSourceWorkspaceConfig, TargetData,
|
ProjectJson, ProjectManifest, Sysroot, SysrootSourceWorkspaceConfig, TargetData, TargetKind,
|
||||||
TargetKind, WorkspaceBuildScripts,
|
WorkspaceBuildScripts,
|
||||||
};
|
};
|
||||||
use tracing::{debug, error, info};
|
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 {
|
impl ProjectWorkspace {
|
||||||
pub fn load(
|
pub fn load(
|
||||||
manifest: ProjectManifest,
|
manifest: ProjectManifest,
|
||||||
|
@ -242,16 +220,52 @@ impl ProjectWorkspace {
|
||||||
.ok_or_else(|| Some("Failed to discover rustc source for sysroot.".to_owned())),
|
.ok_or_else(|| Some("Failed to discover rustc source for sysroot.".to_owned())),
|
||||||
None => Err(None),
|
None => Err(None),
|
||||||
};
|
};
|
||||||
let targets = target_tuple::get(
|
|
||||||
QueryConfig::Cargo(&sysroot, cargo_toml),
|
|
||||||
config.target.as_deref(),
|
|
||||||
&config.extra_env,
|
|
||||||
)
|
|
||||||
.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");
|
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,
|
||||||
|
)
|
||||||
|
.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| {
|
let rustc = rustc_dir.and_then(|rustc_dir| {
|
||||||
info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
|
info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
|
||||||
match CargoWorkspace::fetch_metadata(
|
match CargoWorkspace::fetch_metadata(
|
||||||
|
@ -288,47 +302,9 @@ impl ProjectWorkspace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let toolchain = get_toolchain_version(
|
sysroot.load_workspace(&SysrootSourceWorkspaceConfig::CargoMetadata(
|
||||||
cargo_toml.parent(),
|
sysroot_metadata_config(&config.extra_env, &targets),
|
||||||
&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);
|
|
||||||
Ok(ProjectWorkspace {
|
Ok(ProjectWorkspace {
|
||||||
kind: ProjectWorkspaceKind::Cargo {
|
kind: ProjectWorkspaceKind::Cargo {
|
||||||
cargo,
|
cargo,
|
||||||
|
@ -350,19 +326,7 @@ impl ProjectWorkspace {
|
||||||
Sysroot::new(project_json.sysroot.clone(), project_json.sysroot_src.clone());
|
Sysroot::new(project_json.sysroot.clone(), project_json.sysroot_src.clone());
|
||||||
sysroot.load_workspace(&SysrootSourceWorkspaceConfig::Stitched);
|
sysroot.load_workspace(&SysrootSourceWorkspaceConfig::Stitched);
|
||||||
let query_config = QueryConfig::Rustc(&sysroot, project_json.path().as_ref());
|
let query_config = QueryConfig::Rustc(&sysroot, project_json.path().as_ref());
|
||||||
let toolchain = match get_toolchain_version(
|
let toolchain = version::get(query_config, &config.extra_env).ok().flatten();
|
||||||
project_json.path(),
|
|
||||||
&sysroot,
|
|
||||||
Tool::Rustc,
|
|
||||||
&config.extra_env,
|
|
||||||
"rustc ",
|
|
||||||
) {
|
|
||||||
Ok(it) => it,
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("{e}");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let target = config.target.as_deref();
|
let target = config.target.as_deref();
|
||||||
let rustc_cfg = rustc_cfg::get(query_config, target, &config.extra_env);
|
let rustc_cfg = rustc_cfg::get(query_config, target, &config.extra_env);
|
||||||
|
@ -388,28 +352,15 @@ impl ProjectWorkspace {
|
||||||
None => Sysroot::empty(),
|
None => Sysroot::empty(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let toolchain =
|
let query_config = QueryConfig::Cargo(&sysroot, detached_file);
|
||||||
match get_toolchain_version(dir, &sysroot, Tool::Rustc, &config.extra_env, "rustc ") {
|
let toolchain = version::get(query_config, &config.extra_env).ok().flatten();
|
||||||
Ok(it) => it,
|
let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env)
|
||||||
Err(e) => {
|
.unwrap_or_default();
|
||||||
tracing::error!("{e}");
|
let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env);
|
||||||
None
|
let data_layout = target_data_layout::get(query_config, None, &config.extra_env);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let targets = target_tuple::get(
|
|
||||||
QueryConfig::Cargo(&sysroot, detached_file),
|
|
||||||
config.target.as_deref(),
|
|
||||||
&config.extra_env,
|
|
||||||
)
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
sysroot.load_workspace(&SysrootSourceWorkspaceConfig::CargoMetadata(
|
sysroot.load_workspace(&SysrootSourceWorkspaceConfig::CargoMetadata(
|
||||||
sysroot_metadata_config(&config.extra_env, &targets),
|
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(
|
let cargo_script = CargoWorkspace::fetch_metadata(
|
||||||
detached_file,
|
detached_file,
|
||||||
|
|
Loading…
Reference in a new issue