diff --git a/Cargo.lock b/Cargo.lock index 91daa229a95e3..71be88dbdd15a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -872,6 +872,7 @@ dependencies = [ "semver", "serde", "serde_json", + "shlex", "tracing", "tracing-subscriber", "unified-diff", diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index c7c23d338e5b6..141588e89ec4d 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -31,6 +31,7 @@ rustfix = "0.8.1" semver = { version = "1.0.23", features = ["serde"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +shlex = "1.3.0" tracing = "0.1" tracing-subscriber = { version = "0.3.3", default-features = false, features = ["ansi", "env-filter", "fmt", "parking_lot", "smallvec"] } unified-diff = "0.2.1" diff --git a/src/tools/compiletest/src/directives.rs b/src/tools/compiletest/src/directives.rs index b6a9a5b1b9f5f..0f94ab86cb0fe 100644 --- a/src/tools/compiletest/src/directives.rs +++ b/src/tools/compiletest/src/directives.rs @@ -1380,6 +1380,6 @@ fn split_flags(flags: &str) -> Vec { .split('\'') .enumerate() .flat_map(|(i, f)| if i % 2 == 1 { vec![f] } else { f.split_whitespace().collect() }) - .map(move |s| s.to_owned()) - .collect::>() + .map(|s| s.to_owned()) + .collect() } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index da4ec440bb443..e20f91487fc26 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2835,17 +2835,27 @@ impl<'test> TestCx<'test> { ) { writeln!(self.stderr, "diff of {stream}:\n"); if let Some(diff_command) = self.config.diff_command.as_deref() { - let mut args = diff_command.split_whitespace(); - let name = args.next().unwrap(); - match Command::new(name).args(args).args([expected_path, actual_path]).output() { - Err(err) => { - self.fatal(&format!( - "failed to call custom diff command `{diff_command}`: {err}" - )); + match shlex::split(diff_command) { + Some(mut args) if !args.is_empty() => { + let name = args.remove(0); + match Command::new(name).args(args).args([expected_path, actual_path]).output() + { + Err(err) => { + self.fatal(&format!( + "failed to call custom diff command `{diff_command}`: {err}" + )); + } + Ok(output) => { + let output = String::from_utf8_lossy(&output.stdout); + write!(self.stderr, "{output}"); + } + } } - Ok(output) => { - let output = String::from_utf8_lossy(&output.stdout); - write!(self.stderr, "{output}"); + Some(_) => { + self.fatal(&format!("custom diff command is empty: `{diff_command}`")); + } + None => { + self.fatal(&format!("failed to parse custom diff command: `{diff_command}`")); } } } else {