diff --git a/cargo-miri/src/phases.rs b/cargo-miri/src/phases.rs index 376b191192f4..38bc62436956 100644 --- a/cargo-miri/src/phases.rs +++ b/cargo-miri/src/phases.rs @@ -310,17 +310,17 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { let mut cmd = miri(); // Ensure --emit argument for a check-only build is present. - // We cannot use the usual helpers since we need to check specifically in `env.args`. - if let Some(i) = env.args.iter().position(|arg| arg.starts_with("--emit=")) { + if let Some(val) = ArgFlagValueIter::new(env.args.clone().into_iter(), "--emit").next() + { // For `no_run` tests, rustdoc passes a `--emit` flag; make sure it has the right shape. - assert_eq!(env.args[i], "--emit=metadata"); + assert_eq!(val, "metadata"); } else { // For all other kinds of tests, we can just add our flag. cmd.arg("--emit=metadata"); } // Alter the `-o` parameter so that it does not overwrite the JSON file we stored above. - let mut args = env.args.clone(); + let mut args = env.args; for i in 0..args.len() { if args[i] == "-o" { args[i + 1].push_str(".miri"); @@ -344,7 +344,7 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { return; } - if runnable_crate && ArgFlagValueIter::new("--extern").any(|krate| krate == "proc_macro") { + if runnable_crate && get_arg_flag_values("--extern").any(|krate| krate == "proc_macro") { // This is a "runnable" `proc-macro` crate (unit tests). We do not support // interpreting that under Miri now, so we write a JSON file to (display a // helpful message and) skip it in the runner phase. @@ -568,7 +568,7 @@ pub fn phase_rustdoc(mut args: impl Iterator) { // Doctests of `proc-macro` crates (and their dependencies) are always built for the host, // so we are not able to run them in Miri. - if ArgFlagValueIter::new("--crate-type").any(|crate_type| crate_type == "proc-macro") { + if get_arg_flag_values("--crate-type").any(|crate_type| crate_type == "proc-macro") { eprintln!("Running doctests of `proc-macro` crates is not currently supported by Miri."); return; } diff --git a/cargo-miri/src/util.rs b/cargo-miri/src/util.rs index 729794ed9930..27e312a4662a 100644 --- a/cargo-miri/src/util.rs +++ b/cargo-miri/src/util.rs @@ -81,7 +81,7 @@ pub fn has_arg_flag(name: &str) -> bool { /// Determines how many times a `--flag` is present. pub fn num_arg_flag(name: &str) -> usize { - std::env::args().take_while(|val| val != "--").filter(|val| val == name).count() + env::args().take_while(|val| val != "--").filter(|val| val == name).count() } /// Yields all values of command line flag `name` as `Ok(arg)`, and all other arguments except @@ -121,15 +121,15 @@ impl> Iterator for ArgSplitFlagValue<'_, I> { } /// Yields all values of command line flag `name`. -pub struct ArgFlagValueIter<'a>(ArgSplitFlagValue<'a, env::Args>); +pub struct ArgFlagValueIter<'a, I>(ArgSplitFlagValue<'a, I>); -impl<'a> ArgFlagValueIter<'a> { - pub fn new(name: &'a str) -> Self { - Self(ArgSplitFlagValue::new(env::args(), name)) +impl<'a, I: Iterator> ArgFlagValueIter<'a, I> { + pub fn new(args: I, name: &'a str) -> Self { + Self(ArgSplitFlagValue::new(args, name)) } } -impl Iterator for ArgFlagValueIter<'_> { +impl> Iterator for ArgFlagValueIter<'_, I> { type Item = String; fn next(&mut self) -> Option { @@ -141,9 +141,14 @@ impl Iterator for ArgFlagValueIter<'_> { } } +/// Gets the values of a `--flag`. +pub fn get_arg_flag_values<'a>(name: &'a str) -> impl Iterator + 'a { + ArgFlagValueIter::new(env::args(), name) +} + /// Gets the value of a `--flag`. pub fn get_arg_flag_value(name: &str) -> Option { - ArgFlagValueIter::new(name).next() + get_arg_flag_values(name).next() } /// Escapes `s` in a way that is suitable for using it as a string literal in TOML syntax. @@ -296,7 +301,7 @@ fn cargo_extra_flags() -> Vec { // Forward `--config` flags. let config_flag = "--config"; - for arg in ArgFlagValueIter::new(config_flag) { + for arg in get_arg_flag_values(config_flag) { flags.push(config_flag.to_string()); flags.push(arg); }