1
1
//! Implements the various phases of `cargo miri run/test`.
2
2
3
+ use std:: env;
3
4
use std:: fs:: { self , File } ;
4
- use std:: io:: { BufReader , Write } ;
5
+ use std:: io:: BufReader ;
5
6
use std:: path:: { Path , PathBuf } ;
6
7
use std:: process:: Command ;
7
- use std:: { env, thread} ;
8
8
9
9
use rustc_version:: VersionMeta ;
10
10
@@ -24,10 +24,7 @@ Subcommands:
24
24
clean Clean the Miri cache & target directory
25
25
26
26
The cargo options are exactly the same as for `cargo run` and `cargo test`, respectively.
27
- Furthermore, the following extra flags and environment variables are recognized for `run` and `test`:
28
-
29
- --many-seeds[=from..to] Run the program/tests many times with different seeds in the given range.
30
- The range defaults to `0..64`.
27
+ Furthermore, the following environment variables are recognized for `run` and `test`:
31
28
32
29
MIRIFLAGS Extra flags to pass to the Miri driver. Use this to pass `-Zmiri-...` flags.
33
30
@@ -41,8 +38,6 @@ Examples:
41
38
42
39
" ;
43
40
44
- const DEFAULT_MANY_SEEDS : & str = "0..64" ;
45
-
46
41
fn show_help ( ) {
47
42
println ! ( "{CARGO_MIRI_HELP}" ) ;
48
43
}
@@ -182,17 +177,15 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
182
177
let target_dir = get_target_dir ( & metadata) ;
183
178
cmd. arg ( "--target-dir" ) . arg ( target_dir) ;
184
179
185
- // Store many-seeds argument.
186
- let mut many_seeds = None ;
187
180
// *After* we set all the flags that need setting, forward everything else. Make sure to skip
188
- // `--target-dir` (which would otherwise be set twice) and `--many-seeds` (which is our flag, not cargo's) .
181
+ // `--target-dir` (which would otherwise be set twice).
189
182
for arg in
190
183
ArgSplitFlagValue :: from_string_iter ( & mut args, "--target-dir" ) . filter_map ( Result :: err)
191
184
{
192
- if arg == "--many-seeds" {
193
- many_seeds = Some ( DEFAULT_MANY_SEEDS . to_owned ( ) ) ;
194
- } else if let Some ( val ) = arg . strip_prefix ( " --many-seeds=" ) {
195
- many_seeds = Some ( val . to_owned ( ) ) ;
185
+ if arg == "--many-seeds" || arg . starts_with ( "--many-seeds=" ) {
186
+ show_error ! (
187
+ "ERROR: the ` --many-seeds` flag has been removed from cargo-miri; use MIRIFLAGS=-Zmiri-many-seeds instead"
188
+ ) ;
196
189
} else {
197
190
cmd. arg ( arg) ;
198
191
}
@@ -249,9 +242,6 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
249
242
// Forward some crucial information to our own re-invocations.
250
243
cmd. env ( "MIRI_SYSROOT" , miri_sysroot) ;
251
244
cmd. env ( "MIRI_LOCAL_CRATES" , local_crates ( & metadata) ) ;
252
- if let Some ( many_seeds) = many_seeds {
253
- cmd. env ( "MIRI_MANY_SEEDS" , many_seeds) ;
254
- }
255
245
if verbose > 0 {
256
246
cmd. env ( "MIRI_VERBOSE" , verbose. to_string ( ) ) ; // This makes the other phases verbose.
257
247
}
@@ -407,14 +397,11 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
407
397
408
398
// Alter the `-o` parameter so that it does not overwrite the JSON file we stored above.
409
399
let mut args = env. args ;
410
- let mut out_filename = None ;
411
400
for i in 0 ..args. len ( ) {
412
401
if args[ i] == "-o" {
413
- out_filename = Some ( args[ i + 1 ] . clone ( ) ) ;
414
402
args[ i + 1 ] . push_str ( ".miri" ) ;
415
403
}
416
404
}
417
- let out_filename = out_filename. expect ( "rustdoc must pass `-o`" ) ;
418
405
419
406
cmd. args ( & args) ;
420
407
cmd. env ( "MIRI_BE_RUSTC" , "target" ) ;
@@ -427,7 +414,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
427
414
eprintln ! ( "[cargo-miri rustc inside rustdoc] going to run:\n {cmd:?}" ) ;
428
415
}
429
416
430
- exec_with_pipe ( cmd, & env. stdin , format ! ( "{out_filename}.stdin" ) ) ;
417
+ exec_with_pipe ( cmd, & env. stdin ) ;
431
418
}
432
419
433
420
return ;
@@ -589,111 +576,81 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
589
576
}
590
577
} ;
591
578
592
- let many_seeds = env:: var ( "MIRI_MANY_SEEDS" ) ;
593
- run_many_seeds ( many_seeds. ok ( ) , |seed| {
594
- let mut cmd = miri ( ) ;
595
-
596
- // Set missing env vars. We prefer build-time env vars over run-time ones; see
597
- // <https://github.com/rust-lang/miri/issues/1661> for the kind of issue that fixes.
598
- for ( name, val) in & info. env {
599
- // `CARGO_MAKEFLAGS` contains information about how to reach the jobserver, but by the time
600
- // the program is being run, that jobserver no longer exists (cargo only runs the jobserver
601
- // for the build portion of `cargo run`/`cargo test`). Hence we shouldn't forward this.
602
- // Also see <https://github.com/rust-lang/rust/pull/113730>.
603
- if name == "CARGO_MAKEFLAGS" {
604
- continue ;
605
- }
606
- if let Some ( old_val) = env:: var_os ( name) {
607
- if * old_val == * val {
608
- // This one did not actually change, no need to re-set it.
609
- // (This keeps the `debug_cmd` below more manageable.)
610
- continue ;
611
- } else if verbose > 0 {
612
- eprintln ! (
613
- "[cargo-miri runner] Overwriting run-time env var {name:?}={old_val:?} with build-time value {val:?}"
614
- ) ;
615
- }
616
- }
617
- cmd. env ( name, val) ;
618
- }
579
+ let mut cmd = miri ( ) ;
619
580
620
- if phase != RunnerPhase :: Rustdoc {
621
- // Set the sysroot. Not necessary in rustdoc, where we already set the sysroot in
622
- // `phase_rustdoc`. rustdoc will forward that flag when invoking rustc (i.e., us), so the
623
- // flag is present in `info.args`.
624
- cmd. arg ( "--sysroot" ) . arg ( env:: var_os ( "MIRI_SYSROOT" ) . unwrap ( ) ) ;
581
+ // Set missing env vars. We prefer build-time env vars over run-time ones; see
582
+ // <https://github.com/rust-lang/miri/issues/1661> for the kind of issue that fixes.
583
+ for ( name, val) in & info. env {
584
+ // `CARGO_MAKEFLAGS` contains information about how to reach the jobserver, but by the time
585
+ // the program is being run, that jobserver no longer exists (cargo only runs the jobserver
586
+ // for the build portion of `cargo run`/`cargo test`). Hence we shouldn't forward this.
587
+ // Also see <https://github.com/rust-lang/rust/pull/113730>.
588
+ if name == "CARGO_MAKEFLAGS" {
589
+ continue ;
625
590
}
626
- // Forward rustc arguments.
627
- // We need to patch "--extern" filenames because we forced a check-only
628
- // build without cargo knowing about that: replace `.rlib` suffix by
629
- // `.rmeta`.
630
- // We also need to remove `--error-format` as cargo specifies that to be JSON,
631
- // but when we run here, cargo does not interpret the JSON any more. `--json`
632
- // then also needs to be dropped.
633
- let mut args = info. args . iter ( ) ;
634
- while let Some ( arg) = args. next ( ) {
635
- if arg == "--extern" {
636
- forward_patched_extern_arg ( & mut ( & mut args) . cloned ( ) , & mut cmd) ;
637
- } else if let Some ( suffix) = arg. strip_prefix ( "--error-format" ) {
638
- assert ! ( suffix. starts_with( '=' ) ) ;
639
- // Drop this argument.
640
- } else if let Some ( suffix) = arg. strip_prefix ( "--json" ) {
641
- assert ! ( suffix. starts_with( '=' ) ) ;
642
- // Drop this argument.
643
- } else {
644
- cmd. arg ( arg) ;
591
+ if let Some ( old_val) = env:: var_os ( name) {
592
+ if * old_val == * val {
593
+ // This one did not actually change, no need to re-set it.
594
+ // (This keeps the `debug_cmd` below more manageable.)
595
+ continue ;
596
+ } else if verbose > 0 {
597
+ eprintln ! (
598
+ "[cargo-miri runner] Overwriting run-time env var {name:?}={old_val:?} with build-time value {val:?}"
599
+ ) ;
645
600
}
646
601
}
647
- // Respect `MIRIFLAGS`.
648
- if let Ok ( a) = env:: var ( "MIRIFLAGS" ) {
649
- let args = flagsplit ( & a) ;
650
- cmd. args ( args) ;
651
- }
652
- // Set the current seed.
653
- if let Some ( seed) = seed {
654
- eprintln ! ( "Trying seed: {seed}" ) ;
655
- cmd. arg ( format ! ( "-Zmiri-seed={seed}" ) ) ;
656
- }
602
+ cmd. env ( name, val) ;
603
+ }
657
604
658
- // Then pass binary arguments.
659
- cmd. arg ( "--" ) ;
660
- cmd. args ( & binary_args) ;
661
-
662
- // Make sure we use the build-time working directory for interpreting Miri/rustc arguments.
663
- // But then we need to switch to the run-time one, which we instruct Miri to do by setting `MIRI_CWD`.
664
- cmd. current_dir ( & info. current_dir ) ;
665
- cmd. env ( "MIRI_CWD" , env:: current_dir ( ) . unwrap ( ) ) ;
666
-
667
- // Run it.
668
- debug_cmd ( "[cargo-miri runner]" , verbose, & cmd) ;
669
-
670
- match phase {
671
- RunnerPhase :: Rustdoc => {
672
- cmd. stdin ( std:: process:: Stdio :: piped ( ) ) ;
673
- // the warning is wrong, we have a `wait` inside the `scope` closure.
674
- let mut child = cmd. spawn ( ) . expect ( "failed to spawn process" ) ;
675
- let child_stdin = child. stdin . take ( ) . unwrap ( ) ;
676
- // Write stdin in a background thread, as it may block.
677
- let exit_status = thread:: scope ( |s| {
678
- s. spawn ( || {
679
- let mut child_stdin = child_stdin;
680
- // Ignore failure, it is most likely due to the process having terminated.
681
- let _ = child_stdin. write_all ( & info. stdin ) ;
682
- } ) ;
683
- child. wait ( ) . expect ( "failed to run command" )
684
- } ) ;
685
- if !exit_status. success ( ) {
686
- std:: process:: exit ( exit_status. code ( ) . unwrap_or ( -1 ) ) ;
687
- }
688
- }
689
- RunnerPhase :: Cargo => {
690
- let exit_status = cmd. status ( ) . expect ( "failed to run command" ) ;
691
- if !exit_status. success ( ) {
692
- std:: process:: exit ( exit_status. code ( ) . unwrap_or ( -1 ) ) ;
693
- }
694
- }
605
+ if phase != RunnerPhase :: Rustdoc {
606
+ // Set the sysroot. Not necessary in rustdoc, where we already set the sysroot in
607
+ // `phase_rustdoc`. rustdoc will forward that flag when invoking rustc (i.e., us), so the
608
+ // flag is present in `info.args`.
609
+ cmd. arg ( "--sysroot" ) . arg ( env:: var_os ( "MIRI_SYSROOT" ) . unwrap ( ) ) ;
610
+ }
611
+ // Forward rustc arguments.
612
+ // We need to patch "--extern" filenames because we forced a check-only
613
+ // build without cargo knowing about that: replace `.rlib` suffix by
614
+ // `.rmeta`.
615
+ // We also need to remove `--error-format` as cargo specifies that to be JSON,
616
+ // but when we run here, cargo does not interpret the JSON any more. `--json`
617
+ // then also needs to be dropped.
618
+ let mut args = info. args . iter ( ) ;
619
+ while let Some ( arg) = args. next ( ) {
620
+ if arg == "--extern" {
621
+ forward_patched_extern_arg ( & mut ( & mut args) . cloned ( ) , & mut cmd) ;
622
+ } else if let Some ( suffix) = arg. strip_prefix ( "--error-format" ) {
623
+ assert ! ( suffix. starts_with( '=' ) ) ;
624
+ // Drop this argument.
625
+ } else if let Some ( suffix) = arg. strip_prefix ( "--json" ) {
626
+ assert ! ( suffix. starts_with( '=' ) ) ;
627
+ // Drop this argument.
628
+ } else {
629
+ cmd. arg ( arg) ;
695
630
}
696
- } ) ;
631
+ }
632
+ // Respect `MIRIFLAGS`.
633
+ if let Ok ( a) = env:: var ( "MIRIFLAGS" ) {
634
+ let args = flagsplit ( & a) ;
635
+ cmd. args ( args) ;
636
+ }
637
+
638
+ // Then pass binary arguments.
639
+ cmd. arg ( "--" ) ;
640
+ cmd. args ( & binary_args) ;
641
+
642
+ // Make sure we use the build-time working directory for interpreting Miri/rustc arguments.
643
+ // But then we need to switch to the run-time one, which we instruct Miri to do by setting `MIRI_CWD`.
644
+ cmd. current_dir ( & info. current_dir ) ;
645
+ cmd. env ( "MIRI_CWD" , env:: current_dir ( ) . unwrap ( ) ) ;
646
+
647
+ // Run it.
648
+ debug_cmd ( "[cargo-miri runner]" , verbose, & cmd) ;
649
+
650
+ match phase {
651
+ RunnerPhase :: Rustdoc => exec_with_pipe ( cmd, & info. stdin ) ,
652
+ RunnerPhase :: Cargo => exec ( cmd) ,
653
+ }
697
654
}
698
655
699
656
pub fn phase_rustdoc ( mut args : impl Iterator < Item = String > ) {
0 commit comments