Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Ensure that --error-format is only passed once to rustc #1500

Merged
merged 3 commits into from
Jun 26, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions rls/src/build/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,11 @@ impl Executor for RlsExecutor {
_on_stdout_line: &mut dyn FnMut(&str) -> CargoResult<()>,
_on_stderr_line: &mut dyn FnMut(&str) -> CargoResult<()>,
) -> CargoResult<()> {
// Use JSON output so that we can parse the rustc output.
// Enforce JSON output so that we can parse the rustc output by
// stripping --error-format if it was specified (e.g. Cargo pipelined
// build)
let filtered_args = filter_arg(cargo_cmd.get_args(), "--error-format");
cargo_cmd.args_replace(&filtered_args);
cargo_cmd.arg("--error-format=json");
// Delete any stale data. We try and remove any json files with
// the same crate name as Cargo would emit. This includes files
Expand Down Expand Up @@ -755,6 +759,27 @@ fn dedup_flags(flag_str: &str) -> String {
result
}

/// Removes a selected flag of a `--flag=VALUE` or `--flag VALUE` shape from `args` (command line args for Rust).
fn filter_arg(args: &[OsString], key: &str) -> Vec<String> {
let key_as_prefix = key.to_owned() + "=";
let mut ret = vec![];

let mut iter = args.iter();
while let Some(arg) = iter.next() {
let first = arg.to_str().unwrap();

if first == key {
iter.next();
} else if first.starts_with(&key_as_prefix) {
// no-op
} else {
ret.push(first.to_owned());
}
}

ret
}

/// Error wrapper that tries to figure out which manifest the cause best relates to in the project
#[derive(Debug)]
pub struct ManifestAwareError {
Expand Down Expand Up @@ -837,7 +862,7 @@ impl failure::Fail for ManifestAwareError {

#[cfg(test)]
mod test {
use super::dedup_flags;
use super::{dedup_flags, filter_arg};

#[test]
fn test_dedup_flags() {
Expand Down Expand Up @@ -870,4 +895,21 @@ mod test {
) == " -Clink-args=-fuse-ld=gold -Ctarget-cpu=native"
);
}

#[test]
fn test_filter_arg() {
use std::ffi::OsString;

fn args(input: &str) -> Vec<OsString> {
input.split_whitespace().map(OsString::from).collect()
}

assert!(filter_arg(&args("--error-format=json"), "--error-format").is_empty());
assert!(filter_arg(&args("--error-format json"), "--error-format").is_empty());
assert_eq!(filter_arg(&args("-a --error-format=json"), "--error-format"), ["-a"]);
assert_eq!(filter_arg(&args("-a --error-format json"), "--error-format"), ["-a"]);
assert_eq!(filter_arg(&args("-a --error-format=json -b"), "--error-format"), ["-a", "-b"]);
assert_eq!(filter_arg(&args("-a --error-format json -b"), "--error-format"), ["-a", "-b"]);
assert_eq!(filter_arg(&args("-a -b -x"), "--error-format"), ["-a", "-b", "-x"]);
}
}