diff --git a/src/driver.rs b/src/driver.rs index ea01b6865626..973abc59c1a2 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -21,48 +21,26 @@ use rustc_session::EarlyDiagCtxt; use rustc_span::symbol::Symbol; use std::env; -use std::fs::read_to_string; -use std::ops::Deref; use std::path::Path; use std::process::exit; use anstream::println; -/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If -/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`. -fn arg_value<'a, T: Deref>( - args: &'a [T], - find_arg: &str, - pred: impl Fn(&str) -> bool, -) -> Option<&'a str> { - let mut args = args.iter().map(Deref::deref); - while let Some(arg) = args.next() { - let mut arg = arg.splitn(2, '='); - if arg.next() != Some(find_arg) { - continue; - } - - match arg.next().or_else(|| args.next()) { - Some(v) if pred(v) => return Some(v), - _ => {}, - } - } - None +/// Returns if `args` contains `find_arg`, accounts for `--foo=bar` and `--foo bar` +fn has_arg(args: &[String], find_arg: &str) -> bool { + args.iter().any(|arg| arg.split('=').next().unwrap_or(arg) == find_arg) } #[test] fn test_arg_value() { - let args = &["--bar=bar", "--foobar", "123", "--foo"]; - - assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None); - assert_eq!(arg_value(args, "--bar", |_| false), None); - assert_eq!(arg_value(args, "--bar", |_| true), Some("bar")); - assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar")); - assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None); - assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None); - assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123")); - assert_eq!(arg_value(args, "--foobar", |p| p.contains("12")), Some("123")); - assert_eq!(arg_value(args, "--foo", |_| true), None); + let args = &["--bar=bar", "--foobar", "123", "-vV"].map(String::from); + + assert!(!has_arg(&[], "--foobar")); + assert!(!has_arg(args, "--foo")); + + assert!(has_arg(args, "--bar")); + assert!(has_arg(args, "--foobar")); + assert!(has_arg(args, "-vV")); } fn track_clippy_args(psess: &mut ParseSess, args_env_var: &Option) { @@ -188,24 +166,18 @@ pub fn main() { exit(rustc_driver::catch_with_exit_code(move || { let mut orig_args = rustc_driver::args::raw_args(&early_dcx)?; - let has_sysroot_arg = |args: &mut [String]| -> bool { - if arg_value(args, "--sysroot", |_| true).is_some() { + let has_sysroot_arg = |args: &[String]| -> bool { + if has_arg(args, "--sysroot") { return true; } // https://doc.rust-lang.org/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path // Beside checking for existence of `--sysroot` on the command line, we need to // check for the arg files that are prefixed with @ as well to be consistent with rustc - for arg in args.iter() { - if let Some(arg_file_path) = arg.strip_prefix('@') { - if let Ok(arg_file) = read_to_string(arg_file_path) { - let split_arg_file: Vec = arg_file.lines().map(ToString::to_string).collect(); - if arg_value(&split_arg_file, "--sysroot", |_| true).is_some() { - return true; - } - } - } + if let Ok(expanded) = rustc_driver::args::arg_expand_all(&early_dcx, args) { + has_arg(&expanded, "--sysroot") + } else { + false } - false }; let sys_root_env = std::env::var("SYSROOT").ok(); @@ -275,8 +247,11 @@ pub fn main() { // Disable Clippy if `--no-deps` is passed and we aren't in a primary package let disabled_dep = no_deps && env::var_os("CARGO_PRIMARY_PACKAGE").is_none(); + // Disable Clippy for `-vV`, `--print cfg ...` requests so that malformed `clippy_args` do not end + // up being cached - https://github.com/rust-lang/cargo/issues/14385 + let info_query = has_arg(&args, "-vV") || has_arg(&args, "--print"); - let clippy_enabled = !disabled_dep; + let clippy_enabled = !disabled_dep && !info_query; if clippy_enabled { args.extend(clippy_args); rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var })