From 2ac803ec7115ce3f7a7229edc44ee8f99923bc48 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 7 Jan 2025 12:21:27 +0100 Subject: [PATCH 1/3] target-triple -> target-tuple --- crates/project-model/src/lib.rs | 2 +- .../{target_triple.rs => target_tuple.rs} | 10 +++++----- crates/project-model/src/workspace.rs | 6 +++--- crates/rust-analyzer/src/config.rs | 6 +++--- crates/rust-analyzer/src/flycheck.rs | 4 ++-- docs/user/generated_config.adoc | 2 +- docs/user/manual.adoc | 2 +- editors/code/package.json | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) rename crates/project-model/src/toolchain_info/{target_triple.rs => target_tuple.rs} (88%) diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs index f54054382539..dec4f1456bae 100644 --- a/crates/project-model/src/lib.rs +++ b/crates/project-model/src/lib.rs @@ -19,7 +19,7 @@ pub mod project_json; pub mod toolchain_info { pub mod rustc_cfg; pub mod target_data_layout; - pub mod target_triple; + pub mod target_tuple; use std::path::Path; diff --git a/crates/project-model/src/toolchain_info/target_triple.rs b/crates/project-model/src/toolchain_info/target_tuple.rs similarity index 88% rename from crates/project-model/src/toolchain_info/target_triple.rs rename to crates/project-model/src/toolchain_info/target_tuple.rs index 163884e5e8ba..55e033caeccc 100644 --- a/crates/project-model/src/toolchain_info/target_triple.rs +++ b/crates/project-model/src/toolchain_info/target_tuple.rs @@ -14,7 +14,7 @@ pub fn get( target: Option<&str>, extra_env: &FxHashMap, ) -> anyhow::Result> { - let _p = tracing::info_span!("target_triple::get").entered(); + let _p = tracing::info_span!("target_tuple::get").entered(); if let Some(target) = target { return Ok(vec![target.to_owned()]); } @@ -28,10 +28,10 @@ pub fn get( } QueryConfig::Rustc(sysroot, current_dir) => (sysroot, current_dir), }; - rustc_discover_host_triple(extra_env, sysroot, current_dir).map(|it| vec![it]) + rustc_discover_host_tuple(extra_env, sysroot, current_dir).map(|it| vec![it]) } -fn rustc_discover_host_triple( +fn rustc_discover_host_tuple( extra_env: &FxHashMap, sysroot: &Sysroot, current_dir: &Path, @@ -60,14 +60,14 @@ fn cargo_config_build_target( cmd.envs(extra_env); cmd.current_dir(cargo_toml.parent()).env("RUSTC_BOOTSTRAP", "1"); cmd.args(["-Z", "unstable-options", "config", "get", "build.target"]); - // if successful we receive `build.target = "target-triple"` + // if successful we receive `build.target = "target-tuple"` // or `build.target = ["", ..]` // this might be `error: config value `build.target` is not set` in which case we // don't wanna log the error utf8_stdout(&mut cmd).and_then(parse_output_cargo_config_build_target).ok() } -// Parses `"build.target = [target-triple, target-triple, ...]"` or `"build.target = "target-triple"` +// Parses `"build.target = [target-tuple, target-tuple, ...]"` or `"build.target = "target-tuple"` fn parse_output_cargo_config_build_target(stdout: String) -> anyhow::Result> { let trimmed = stdout.trim_start_matches("build.target = ").trim_matches('"'); diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 6dc8e2fa5d8e..905e83b27d1a 100644 --- a/crates/project-model/src/workspace.rs +++ b/crates/project-model/src/workspace.rs @@ -26,7 +26,7 @@ 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_triple, QueryConfig}, + 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, @@ -242,7 +242,7 @@ impl ProjectWorkspace { .ok_or_else(|| Some("Failed to discover rustc source for sysroot.".to_owned())), None => Err(None), }; - let targets = target_triple::get( + let targets = target_tuple::get( QueryConfig::Cargo(&sysroot, cargo_toml), config.target.as_deref(), &config.extra_env, @@ -397,7 +397,7 @@ impl ProjectWorkspace { } }; - let targets = target_triple::get( + let targets = target_tuple::get( QueryConfig::Cargo(&sysroot, detached_file), config.target.as_deref(), &config.extra_env, diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 67e0a208e8c4..30f0031905f1 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -600,7 +600,7 @@ config_data! { /// /// This option does not take effect until rust-analyzer is restarted. cargo_sysrootSrc: Option = None, - /// Compilation target override (target triple). + /// Compilation target override (target tuple). // FIXME(@poliorcetics): move to multiple targets here too, but this will need more work // than `checkOnSave_target` cargo_target: Option = None, @@ -2041,7 +2041,7 @@ impl Config { pub(crate) fn cargo_test_options(&self, source_root: Option) -> CargoOptions { CargoOptions { - target_triples: self.cargo_target(source_root).clone().into_iter().collect(), + target_tuples: self.cargo_target(source_root).clone().into_iter().collect(), all_targets: false, no_default_features: *self.cargo_noDefaultFeatures(source_root), all_features: matches!(self.cargo_features(source_root), CargoFeaturesDef::All), @@ -2076,7 +2076,7 @@ impl Config { Some(_) | None => FlycheckConfig::CargoCommand { command: self.check_command(source_root).clone(), options: CargoOptions { - target_triples: self + target_tuples: self .check_targets(source_root) .clone() .and_then(|targets| match &targets.0[..] { diff --git a/crates/rust-analyzer/src/flycheck.rs b/crates/rust-analyzer/src/flycheck.rs index a306302cc0eb..98042a2bcebf 100644 --- a/crates/rust-analyzer/src/flycheck.rs +++ b/crates/rust-analyzer/src/flycheck.rs @@ -28,7 +28,7 @@ pub(crate) enum InvocationStrategy { #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct CargoOptions { - pub(crate) target_triples: Vec, + pub(crate) target_tuples: Vec, pub(crate) all_targets: bool, pub(crate) no_default_features: bool, pub(crate) all_features: bool, @@ -49,7 +49,7 @@ pub(crate) enum Target { impl CargoOptions { pub(crate) fn apply_on_command(&self, cmd: &mut Command) { - for target in &self.target_triples { + for target in &self.target_tuples { cmd.args(["--target", target.as_str()]); } if self.all_targets { diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc index 2c6ff4fb01e1..5b86766aa8ea 100644 --- a/docs/user/generated_config.adoc +++ b/docs/user/generated_config.adoc @@ -146,7 +146,7 @@ This option does not take effect until rust-analyzer is restarted. [[rust-analyzer.cargo.target]]rust-analyzer.cargo.target (default: `null`):: + -- -Compilation target override (target triple). +Compilation target override (target tuple). -- [[rust-analyzer.cargo.targetDir]]rust-analyzer.cargo.targetDir (default: `null`):: + diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc index da2aa4eae4e4..ffc820e9b7f7 100644 --- a/docs/user/manual.adoc +++ b/docs/user/manual.adoc @@ -769,7 +769,7 @@ interface Crate { /// The set of cfgs activated for a given crate, like /// `["unix", "feature=\"foo\"", "feature=\"bar\""]`. cfg: string[]; - /// Target triple for this Crate. + /// Target tuple for this Crate. /// /// Used when running `rustc --print cfg` /// to get target-specific cfgs. diff --git a/editors/code/package.json b/editors/code/package.json index 6ec7032c0b2d..80246bf3feac 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -888,7 +888,7 @@ "title": "cargo", "properties": { "rust-analyzer.cargo.target": { - "markdownDescription": "Compilation target override (target triple).", + "markdownDescription": "Compilation target override (target tuple).", "default": null, "type": [ "null", From b8a0488740d147d4c4bb024cb4b3c418531f558f Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 7 Jan 2025 12:34:22 +0100 Subject: [PATCH 2/3] Align toolchain version fetching with other toolchain info querying Fix --target flag argument order in rustc_cfg fetching --- crates/project-model/src/lib.rs | 1 + .../src/toolchain_info/rustc_cfg.rs | 5 +- .../src/toolchain_info/version.rs | 32 ++++ crates/project-model/src/workspace.rs | 165 ++++++------------ 4 files changed, 93 insertions(+), 110 deletions(-) create mode 100644 crates/project-model/src/toolchain_info/version.rs diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs index dec4f1456bae..fc1fd7b877fc 100644 --- a/crates/project-model/src/lib.rs +++ b/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/crates/project-model/src/toolchain_info/rustc_cfg.rs b/crates/project-model/src/toolchain_info/rustc_cfg.rs index b1e8c3376a16..791d1773d732 100644 --- a/crates/project-model/src/toolchain_info/rustc_cfg.rs +++ b/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/crates/project-model/src/toolchain_info/version.rs b/crates/project-model/src/toolchain_info/version.rs new file mode 100644 index 000000000000..a873944dd8a8 --- /dev/null +++ b/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, +) -> Result, 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/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs index 905e83b27d1a..95f8bb9950a4 100644 --- a/crates/project-model/src/workspace.rs +++ b/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, - prefix: &str, -) -> Result, 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, From 59c8e27acca035cae57ef7dfe9309a2258d3f496 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 7 Jan 2025 13:48:35 +0100 Subject: [PATCH 3/3] Add some smoke tests to toolchain_info --- .../src/toolchain_info/rustc_cfg.rs | 26 ++++++++++ .../src/toolchain_info/target_data_layout.rs | 26 ++++++++++ .../src/toolchain_info/target_tuple.rs | 26 ++++++++++ .../src/toolchain_info/version.rs | 26 ++++++++++ crates/project-model/src/workspace.rs | 48 ++++++++++--------- 5 files changed, 129 insertions(+), 23 deletions(-) diff --git a/crates/project-model/src/toolchain_info/rustc_cfg.rs b/crates/project-model/src/toolchain_info/rustc_cfg.rs index 791d1773d732..afcc81207949 100644 --- a/crates/project-model/src/toolchain_info/rustc_cfg.rs +++ b/crates/project-model/src/toolchain_info/rustc_cfg.rs @@ -96,3 +96,29 @@ fn rustc_print_cfg( utf8_stdout(&mut cmd).with_context(|| format!("unable to fetch cfgs via `{cmd:?}`")) } + +#[cfg(test)] +mod tests { + use paths::{AbsPathBuf, Utf8PathBuf}; + + use crate::{ManifestPath, Sysroot}; + + use super::*; + + #[test] + fn cargo() { + let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml"); + let sysroot = Sysroot::empty(); + let manifest_path = + ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap(); + let cfg = QueryConfig::Cargo(&sysroot, &manifest_path); + assert_ne!(get(cfg, None, &FxHashMap::default()), vec![]); + } + + #[test] + fn rustc() { + let sysroot = Sysroot::empty(); + let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref()); + assert_ne!(get(cfg, None, &FxHashMap::default()), vec![]); + } +} diff --git a/crates/project-model/src/toolchain_info/target_data_layout.rs b/crates/project-model/src/toolchain_info/target_data_layout.rs index 9986c661311e..94645a91f65b 100644 --- a/crates/project-model/src/toolchain_info/target_data_layout.rs +++ b/crates/project-model/src/toolchain_info/target_data_layout.rs @@ -55,3 +55,29 @@ pub fn get( .with_context(|| format!("unable to fetch target-data-layout via `{cmd:?}`")) .and_then(process) } + +#[cfg(test)] +mod tests { + use paths::{AbsPathBuf, Utf8PathBuf}; + + use crate::{ManifestPath, Sysroot}; + + use super::*; + + #[test] + fn cargo() { + let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml"); + let sysroot = Sysroot::empty(); + let manifest_path = + ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap(); + let cfg = QueryConfig::Cargo(&sysroot, &manifest_path); + assert!(get(cfg, None, &FxHashMap::default()).is_ok()); + } + + #[test] + fn rustc() { + let sysroot = Sysroot::empty(); + let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref()); + assert!(get(cfg, None, &FxHashMap::default()).is_ok()); + } +} diff --git a/crates/project-model/src/toolchain_info/target_tuple.rs b/crates/project-model/src/toolchain_info/target_tuple.rs index 55e033caeccc..0476de58f230 100644 --- a/crates/project-model/src/toolchain_info/target_tuple.rs +++ b/crates/project-model/src/toolchain_info/target_tuple.rs @@ -77,3 +77,29 @@ fn parse_output_cargo_config_build_target(stdout: String) -> anyhow::Result