@@ -113,30 +113,17 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
113113 } ;
114114 let metadata = get_cargo_metadata ( ) ;
115115 let mut cmd = cargo ( ) ;
116- cmd. arg ( cargo_cmd) ;
117-
118- // Forward all arguments before `--` other than `--target-dir` and its value to Cargo.
119- // (We want to *change* the target-dir value, so we must not forward it.)
120- let mut target_dir = None ;
121- for arg in ArgSplitFlagValue :: from_string_iter ( & mut args, "--target-dir" ) {
122- match arg {
123- Ok ( value) => {
124- if target_dir. is_some ( ) {
125- show_error ! ( "`--target-dir` is provided more than once" ) ;
126- }
127- target_dir = Some ( value. into ( ) ) ;
128- }
129- Err ( arg) => {
130- cmd. arg ( arg) ;
131- }
132- }
116+ cmd. arg ( & cargo_cmd) ;
117+ // In nextest we have to also forward the main `verb`.
118+ if cargo_cmd == "nextest" {
119+ cmd. arg (
120+ args. next ( )
121+ . unwrap_or_else ( || show_error ! ( "`cargo miri nextest` expects a verb (e.g. `run`)" ) ) ,
122+ ) ;
133123 }
134- // Detect the target directory if it's not specified via `--target-dir`.
135- // (`cargo metadata` does not support `--target-dir`, that's why we have to handle this ourselves.)
136- let target_dir = target_dir. get_or_insert_with ( || metadata. target_directory . clone ( ) ) ;
137- // Set `--target-dir` to `miri` inside the original target directory.
138- target_dir. push ( "miri" ) ;
139- cmd. arg ( "--target-dir" ) . arg ( target_dir) ;
124+ // We set the following flags *before* forwarding more arguments.
125+ // This is needed to fix <https://github.com/rust-lang/miri/issues/2829>: cargo will stop
126+ // interpreting things as flags when it sees the first positional argument.
140127
141128 // Make sure the build target is explicitly set.
142129 // This is needed to make the `target.runner` settings do something,
@@ -154,8 +141,23 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
154141 cmd. arg ( "--config" )
155142 . arg ( format ! ( "target.'cfg(all())'.runner=[{cargo_miri_path_for_toml}, 'runner']" ) ) ;
156143
157- // Forward all further arguments after `--` to cargo.
158- cmd. arg ( "--" ) . args ( args) ;
144+ // Set `--target-dir` to `miri` inside the original target directory.
145+ let mut target_dir = match get_arg_flag_value ( "--target-dir" ) {
146+ Some ( dir) => PathBuf :: from ( dir) ,
147+ None => metadata. target_directory . clone ( ) . into_std_path_buf ( ) ,
148+ } ;
149+ target_dir. push ( "miri" ) ;
150+ cmd. arg ( "--target-dir" ) . arg ( target_dir) ;
151+
152+ // *After* we set all the flags that need setting, forward everything else. Make sure to skip
153+ // `--target-dir` (which would otherwise be set twice).
154+ for arg in
155+ ArgSplitFlagValue :: from_string_iter ( & mut args, "--target-dir" ) . filter_map ( Result :: err)
156+ {
157+ cmd. arg ( arg) ;
158+ }
159+ // Forward all further arguments (not consumed by `ArgSplitFlagValue`) to cargo.
160+ cmd. args ( args) ;
159161
160162 // Set `RUSTC_WRAPPER` to ourselves. Cargo will prepend that binary to its usual invocation,
161163 // i.e., the first argument is `rustc` -- which is what we use in `main` to distinguish
0 commit comments