summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs')
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs50
1 files changed, 36 insertions, 14 deletions
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index b4c2ba436..02ec7a4f6 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -270,11 +270,7 @@ impl CargoWorkspace {
config: &CargoConfig,
progress: &dyn Fn(String),
) -> Result<cargo_metadata::Metadata> {
- let target = config
- .target
- .clone()
- .or_else(|| cargo_config_build_target(cargo_toml, &config.extra_env))
- .or_else(|| rustc_discover_host_triple(cargo_toml, &config.extra_env));
+ let targets = find_list_of_build_targets(config, cargo_toml);
let mut meta = MetadataCommand::new();
meta.cargo_path(toolchain::cargo());
@@ -294,8 +290,12 @@ impl CargoWorkspace {
}
meta.current_dir(current_dir.as_os_str());
- if let Some(target) = target {
- meta.other_options(vec![String::from("--filter-platform"), target]);
+ if !targets.is_empty() {
+ let other_options: Vec<_> = targets
+ .into_iter()
+ .flat_map(|target| ["--filter-platform".to_string(), target])
+ .collect();
+ meta.other_options(other_options);
}
// FIXME: Fetching metadata is a slow process, as it might require
@@ -469,6 +469,19 @@ impl CargoWorkspace {
}
}
+fn find_list_of_build_targets(config: &CargoConfig, cargo_toml: &ManifestPath) -> Vec<String> {
+ if let Some(target) = &config.target {
+ return [target.into()].to_vec();
+ }
+
+ let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env);
+ if !build_targets.is_empty() {
+ return build_targets;
+ }
+
+ rustc_discover_host_triple(cargo_toml, &config.extra_env).into_iter().collect()
+}
+
fn rustc_discover_host_triple(
cargo_toml: &ManifestPath,
extra_env: &FxHashMap<String, String>,
@@ -499,7 +512,7 @@ fn rustc_discover_host_triple(
fn cargo_config_build_target(
cargo_toml: &ManifestPath,
extra_env: &FxHashMap<String, String>,
-) -> Option<String> {
+) -> Vec<String> {
let mut cargo_config = Command::new(toolchain::cargo());
cargo_config.envs(extra_env);
cargo_config
@@ -507,12 +520,21 @@ fn cargo_config_build_target(
.args(&["-Z", "unstable-options", "config", "get", "build.target"])
.env("RUSTC_BOOTSTRAP", "1");
// if successful we receive `build.target = "target-triple"`
+ // or `build.target = ["<target 1>", ..]`
tracing::debug!("Discovering cargo config target by {:?}", cargo_config);
- match utf8_stdout(cargo_config) {
- Ok(stdout) => stdout
- .strip_prefix("build.target = \"")
- .and_then(|stdout| stdout.strip_suffix('"'))
- .map(ToOwned::to_owned),
- Err(_) => None,
+ utf8_stdout(cargo_config).map(parse_output_cargo_config_build_target).unwrap_or_default()
+}
+
+fn parse_output_cargo_config_build_target(stdout: String) -> Vec<String> {
+ let trimmed = stdout.trim_start_matches("build.target = ").trim_matches('"');
+
+ if !trimmed.starts_with('[') {
+ return [trimmed.to_string()].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()
}