Skip to content

Commit f35f020

Browse files
committed
feat: Support passing multiple targets to cargo (for Rust 1.64.0+)
1 parent 7955451 commit f35f020

File tree

6 files changed

+56
-33
lines changed

6 files changed

+56
-33
lines changed

crates/flycheck/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub enum InvocationLocation {
3939
pub enum FlycheckConfig {
4040
CargoCommand {
4141
command: String,
42-
target_triple: Option<String>,
42+
target_triples: Vec<String>,
4343
all_targets: bool,
4444
no_default_features: bool,
4545
all_features: bool,
@@ -285,7 +285,7 @@ impl FlycheckActor {
285285
let (mut cmd, args) = match &self.config {
286286
FlycheckConfig::CargoCommand {
287287
command,
288-
target_triple,
288+
target_triples,
289289
no_default_features,
290290
all_targets,
291291
all_features,
@@ -297,7 +297,7 @@ impl FlycheckActor {
297297
cmd.arg(command);
298298
cmd.args(&["--workspace", "--message-format=json"]);
299299

300-
if let Some(target) = target_triple {
300+
for target in target_triples {
301301
cmd.args(&["--target", target.as_str()]);
302302
}
303303
if *all_targets {

crates/project-model/src/build_scripts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl WorkspaceBuildScripts {
6969
cmd.args(&["check", "--quiet", "--workspace", "--message-format=json"]);
7070

7171
// --all-targets includes tests, benches and examples in addition to the
72-
// default lib and bins. This is an independent concept from the --targets
72+
// default lib and bins. This is an independent concept from the --target
7373
// flag below.
7474
cmd.arg("--all-targets");
7575

crates/project-model/src/cargo_workspace.rs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,7 @@ impl CargoWorkspace {
270270
config: &CargoConfig,
271271
progress: &dyn Fn(String),
272272
) -> Result<cargo_metadata::Metadata> {
273-
let target = config
274-
.target
275-
.clone()
276-
.or_else(|| cargo_config_build_target(cargo_toml, &config.extra_env))
277-
.or_else(|| rustc_discover_host_triple(cargo_toml, &config.extra_env));
273+
let targets = find_list_of_build_targets(config, cargo_toml);
278274

279275
let mut meta = MetadataCommand::new();
280276
meta.cargo_path(toolchain::cargo());
@@ -294,8 +290,12 @@ impl CargoWorkspace {
294290
}
295291
meta.current_dir(current_dir.as_os_str());
296292

297-
if let Some(target) = target {
298-
meta.other_options(vec![String::from("--filter-platform"), target]);
293+
if !targets.is_empty() {
294+
let other_options: Vec<_> = targets
295+
.into_iter()
296+
.flat_map(|target| ["--filter-platform".to_string(), target])
297+
.collect();
298+
meta.other_options(other_options);
299299
}
300300

301301
// FIXME: Fetching metadata is a slow process, as it might require
@@ -469,6 +469,19 @@ impl CargoWorkspace {
469469
}
470470
}
471471

472+
fn find_list_of_build_targets(config: &CargoConfig, cargo_toml: &ManifestPath) -> Vec<String> {
473+
if let Some(target) = &config.target {
474+
return [target.into()].to_vec();
475+
}
476+
477+
let build_targets = cargo_config_build_target(cargo_toml, &config.extra_env);
478+
if !build_targets.is_empty() {
479+
return build_targets;
480+
}
481+
482+
rustc_discover_host_triple(cargo_toml, &config.extra_env).into_iter().collect()
483+
}
484+
472485
fn rustc_discover_host_triple(
473486
cargo_toml: &ManifestPath,
474487
extra_env: &FxHashMap<String, String>,
@@ -499,20 +512,29 @@ fn rustc_discover_host_triple(
499512
fn cargo_config_build_target(
500513
cargo_toml: &ManifestPath,
501514
extra_env: &FxHashMap<String, String>,
502-
) -> Option<String> {
515+
) -> Vec<String> {
503516
let mut cargo_config = Command::new(toolchain::cargo());
504517
cargo_config.envs(extra_env);
505518
cargo_config
506519
.current_dir(cargo_toml.parent())
507520
.args(&["-Z", "unstable-options", "config", "get", "build.target"])
508521
.env("RUSTC_BOOTSTRAP", "1");
509522
// if successful we receive `build.target = "target-triple"`
523+
// or `build.target = ["<target 1>", ..]`
510524
tracing::debug!("Discovering cargo config target by {:?}", cargo_config);
511-
match utf8_stdout(cargo_config) {
512-
Ok(stdout) => stdout
513-
.strip_prefix("build.target = \"")
514-
.and_then(|stdout| stdout.strip_suffix('"'))
515-
.map(ToOwned::to_owned),
516-
Err(_) => None,
525+
utf8_stdout(cargo_config).map(parse_output_cargo_config_build_target).unwrap_or_default()
526+
}
527+
528+
fn parse_output_cargo_config_build_target(stdout: String) -> Vec<String> {
529+
let trimmed = stdout.trim_start_matches("build.target = ").trim_matches('"');
530+
531+
if !trimmed.starts_with('[') {
532+
return [trimmed.to_string()].to_vec();
533+
}
534+
535+
let res = serde_json::from_str(trimmed);
536+
if let Err(e) = &res {
537+
tracing::warn!("Failed to parse `build.target` as an array of target: {}`", e);
517538
}
539+
res.unwrap_or_default()
518540
}

crates/rust-analyzer/src/config.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ config_data! {
115115
/// This option does not take effect until rust-analyzer is restarted.
116116
cargo_sysroot: Option<String> = "\"discover\"",
117117
/// Compilation target override (target triple).
118+
// FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
119+
// than `checkOnSave_target`
118120
cargo_target: Option<String> = "null",
119121
/// Unsets `#[cfg(test)]` for the specified crates.
120122
cargo_unsetTest: Vec<String> = "[\"core\"]",
@@ -171,9 +173,9 @@ config_data! {
171173
/// ```
172174
/// .
173175
checkOnSave_overrideCommand: Option<Vec<String>> = "null",
174-
/// Check for a specific target. Defaults to
176+
/// Check for specific targets. Defaults to
175177
/// `#rust-analyzer.cargo.target#`.
176-
checkOnSave_target: Option<String> = "null",
178+
checkOnSave_target: Vec<String> = "[]",
177179

178180
/// Toggles the additional completions that automatically add imports when completed.
179181
/// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
@@ -1140,11 +1142,10 @@ impl Config {
11401142
}
11411143
Some(_) | None => FlycheckConfig::CargoCommand {
11421144
command: self.data.checkOnSave_command.clone(),
1143-
target_triple: self
1144-
.data
1145-
.checkOnSave_target
1146-
.clone()
1147-
.or_else(|| self.data.cargo_target.clone()),
1145+
target_triples: match self.data.checkOnSave_target.is_empty() {
1146+
false => self.data.checkOnSave_target.clone(),
1147+
true => self.data.cargo_target.clone().into_iter().collect(),
1148+
},
11481149
all_targets: self.data.checkOnSave_allTargets,
11491150
no_default_features: self
11501151
.data

docs/user/generated_config.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,10 @@ cargo check --workspace --message-format=json --all-targets
184184
```
185185
.
186186
--
187-
[[rust-analyzer.checkOnSave.target]]rust-analyzer.checkOnSave.target (default: `null`)::
187+
[[rust-analyzer.checkOnSave.target]]rust-analyzer.checkOnSave.target (default: `[]`)::
188188
+
189189
--
190-
Check for a specific target. Defaults to
190+
Check for specific targets. Defaults to
191191
`#rust-analyzer.cargo.target#`.
192192
--
193193
[[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::

editors/code/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -629,12 +629,12 @@
629629
}
630630
},
631631
"rust-analyzer.checkOnSave.target": {
632-
"markdownDescription": "Check for a specific target. Defaults to\n`#rust-analyzer.cargo.target#`.",
633-
"default": null,
634-
"type": [
635-
"null",
636-
"string"
637-
]
632+
"markdownDescription": "Check for specific targets. Defaults to\n`#rust-analyzer.cargo.target#`.",
633+
"default": [],
634+
"type": "array",
635+
"items": {
636+
"type": "string"
637+
}
638638
},
639639
"rust-analyzer.completion.autoimport.enable": {
640640
"markdownDescription": "Toggles the additional completions that automatically add imports when completed.\nNote that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.",

0 commit comments

Comments
 (0)