@@ -413,14 +413,14 @@ path = "lib.rs"
413
413
// for target crates.
414
414
// We set ourselves (`cargo-miri`) instead of Miri directly to be able to patch the flags
415
415
// for `libpanic_abort` (usually this is done by bootstrap but we have to do it ourselves).
416
- // The `MIRI_BE_RUSTC ` will mean we dispatch to `phase_setup_rustc`.
416
+ // The `MIRI_CALLED_FROM_XARGO ` will mean we dispatch to `phase_setup_rustc`.
417
417
let cargo_miri_path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
418
418
if env:: var_os ( "RUSTC_STAGE" ) . is_some ( ) {
419
419
command. env ( "RUSTC_REAL" , & cargo_miri_path) ;
420
420
} else {
421
421
command. env ( "RUSTC" , & cargo_miri_path) ;
422
422
}
423
- command. env ( "MIRI_BE_RUSTC " , "target " ) ;
423
+ command. env ( "MIRI_CALLED_FROM_XARGO " , "1 " ) ;
424
424
// Make sure there are no other wrappers or flags getting in our way
425
425
// (Cc https://github.com/rust-lang/miri/issues/1421).
426
426
// This is consistent with normal `cargo build` that does not apply `RUSTFLAGS`
@@ -450,21 +450,6 @@ path = "lib.rs"
450
450
}
451
451
}
452
452
453
- fn phase_setup_rustc ( args : env:: Args ) {
454
- // Mostly we just forward everything.
455
- // `MIRI_BE_RUST` is already set.
456
- let mut cmd = miri ( ) ;
457
- cmd. args ( args) ;
458
-
459
- // Patch the panic runtime for `libpanic_abort` (mirroring what bootstrap usually does).
460
- if get_arg_flag_value ( "--crate-name" ) . as_deref ( ) == Some ( "panic_abort" ) {
461
- cmd. arg ( "-C" ) . arg ( "panic=abort" ) ;
462
- }
463
-
464
- // Run it!
465
- exec ( cmd) ;
466
- }
467
-
468
453
fn phase_cargo_miri ( mut args : env:: Args ) {
469
454
// Check for version and help flags even when invoked as `cargo-miri`.
470
455
if has_arg_flag ( "--help" ) || has_arg_flag ( "-h" ) {
@@ -598,7 +583,17 @@ fn phase_cargo_miri(mut args: env::Args) {
598
583
exec ( cmd)
599
584
}
600
585
601
- fn phase_cargo_rustc ( mut args : env:: Args ) {
586
+ #[ derive( Debug , Copy , Clone , PartialEq ) ]
587
+ enum RustcPhase {
588
+ /// `rustc` called via `xargo` for sysroot build.
589
+ Setup ,
590
+ /// `rustc` called by `cargo` for regular build.
591
+ Build ,
592
+ /// `rustc` called by `rustdoc` for doctest.
593
+ Rustdoc ,
594
+ }
595
+
596
+ fn phase_rustc ( mut args : env:: Args , phase : RustcPhase ) {
602
597
/// Determines if we are being invoked (as rustc) to build a crate for
603
598
/// the "target" architecture, in contrast to the "host" architecture.
604
599
/// Host crates are for build scripts and proc macros and still need to
@@ -644,7 +639,7 @@ fn phase_cargo_rustc(mut args: env::Args) {
644
639
645
640
let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
646
641
let target_crate = is_target_crate ( ) ;
647
- let print = get_arg_flag_value ( "--print" ) . is_some ( ) ; // whether this is cargo passing `--print` to get some infos
642
+ let print = get_arg_flag_value ( "--print" ) . is_some ( ) || has_arg_flag ( "-vV" ) ; // whether this is cargo/xargo invoking rustc to get some infos
648
643
649
644
let store_json = |info : CrateRunInfo | {
650
645
// Create a stub .d file to stop Cargo from "rebuilding" the crate:
@@ -669,7 +664,8 @@ fn phase_cargo_rustc(mut args: env::Args) {
669
664
let runnable_crate = !print && is_runnable_crate ( ) ;
670
665
671
666
if runnable_crate && target_crate {
672
- let inside_rustdoc = env:: var_os ( "MIRI_CALLED_FROM_RUSTDOC" ) . is_some ( ) ;
667
+ assert ! ( phase != RustcPhase :: Setup , "there should be no interpretation during sysroot build" ) ;
668
+ let inside_rustdoc = phase == RustcPhase :: Rustdoc ;
673
669
// This is the binary or test crate that we want to interpret under Miri.
674
670
// But we cannot run it here, as cargo invoked us as a compiler -- our stdin and stdout are not
675
671
// like we want them.
@@ -749,8 +745,15 @@ fn phase_cargo_rustc(mut args: env::Args) {
749
745
}
750
746
}
751
747
752
- // Use our custom sysroot.
753
- forward_miri_sysroot ( & mut cmd) ;
748
+ // Use our custom sysroot (but not if that is what we are currently building).
749
+ if phase != RustcPhase :: Setup {
750
+ forward_miri_sysroot ( & mut cmd) ;
751
+ }
752
+
753
+ // During setup, patch the panic runtime for `libpanic_abort` (mirroring what bootstrap usually does).
754
+ if phase == RustcPhase :: Setup && get_arg_flag_value ( "--crate-name" ) . as_deref ( ) == Some ( "panic_abort" ) {
755
+ cmd. arg ( "-C" ) . arg ( "panic=abort" ) ;
756
+ }
754
757
} else {
755
758
// For host crates or when we are printing, just forward everything.
756
759
cmd. args ( args) ;
@@ -783,7 +786,15 @@ fn phase_cargo_rustc(mut args: env::Args) {
783
786
}
784
787
}
785
788
786
- fn phase_cargo_runner ( binary : & Path , binary_args : env:: Args ) {
789
+ #[ derive( Debug , Copy , Clone , PartialEq ) ]
790
+ enum RunnerPhase {
791
+ /// `cargo` is running a binary
792
+ Cargo ,
793
+ /// `rustdoc` is running a binary
794
+ Rustdoc ,
795
+ }
796
+
797
+ fn phase_runner ( binary : & Path , binary_args : env:: Args , phase : RunnerPhase ) {
787
798
let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
788
799
789
800
let file = File :: open ( & binary)
@@ -840,8 +851,8 @@ fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
840
851
cmd. arg ( arg) ;
841
852
}
842
853
}
843
- if env :: var_os ( "MIRI_CALLED_FROM_RUSTDOC" ) . is_none ( ) {
844
- // Set sysroot ( if we are inside rustdoc, we already did that in `phase_cargo_rustdoc`).
854
+ // Set sysroot (if we are inside rustdoc, we already did that in `phase_cargo_rustdoc`).
855
+ if phase != RunnerPhase :: Rustdoc {
845
856
forward_miri_sysroot ( & mut cmd) ;
846
857
}
847
858
// Respect `MIRIFLAGS`.
@@ -869,14 +880,17 @@ fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
869
880
eprintln ! ( "[cargo-miri runner] {:?}" , cmd) ;
870
881
}
871
882
872
- if std:: env:: var_os ( "MIRI_CALLED_FROM_RUSTDOC" ) . is_some ( ) {
873
- exec_with_pipe ( cmd, & info. stdin )
874
- } else {
875
- exec ( cmd)
883
+ match phase {
884
+ RunnerPhase :: Rustdoc => {
885
+ exec_with_pipe ( cmd, & info. stdin )
886
+ }
887
+ RunnerPhase :: Cargo => {
888
+ exec ( cmd)
889
+ }
876
890
}
877
891
}
878
892
879
- fn phase_cargo_rustdoc ( fst_arg : & str , mut args : env:: Args ) {
893
+ fn phase_rustdoc ( fst_arg : & str , mut args : env:: Args ) {
880
894
let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
881
895
882
896
// phase_cargo_miri sets the RUSTDOC env var to ourselves, so we can't use that here;
@@ -950,15 +964,14 @@ fn main() {
950
964
args. next ( ) . unwrap ( ) ;
951
965
952
966
// Dispatch running as part of sysroot compilation.
953
- if env:: var_os ( "MIRI_BE_RUSTC " ) . is_some ( ) {
954
- phase_setup_rustc ( args) ;
967
+ if env:: var_os ( "MIRI_CALLED_FROM_XARGO " ) . is_some ( ) {
968
+ phase_rustc ( args, RustcPhase :: Setup ) ;
955
969
return ;
956
970
}
957
971
958
972
// The way rustdoc invokes rustc is indistuingishable from the way cargo invokes rustdoc by the
959
973
// arguments alone. `phase_cargo_rustdoc` sets this environment variable to let us disambiguate.
960
- let invoked_by_rustdoc = env:: var_os ( "MIRI_CALLED_FROM_RUSTDOC" ) . is_some ( ) ;
961
- if invoked_by_rustdoc {
974
+ if env:: var_os ( "MIRI_CALLED_FROM_RUSTDOC" ) . is_some ( ) {
962
975
// ...however, we then also see this variable when rustdoc invokes us as the testrunner!
963
976
// The runner is invoked as `$runtool ($runtool-arg)* output_file`;
964
977
// since we don't specify any runtool-args, and rustdoc supplies multiple arguments to
@@ -967,12 +980,12 @@ fn main() {
967
980
let arg = args. next ( ) . unwrap ( ) ;
968
981
let binary = Path :: new ( & arg) ;
969
982
if binary. exists ( ) {
970
- phase_cargo_runner ( binary, args) ;
983
+ phase_runner ( binary, args, RunnerPhase :: Rustdoc ) ;
971
984
} else {
972
985
show_error ( format ! ( "`cargo-miri` called with non-existing path argument `{}` in rustdoc mode; please invoke this binary through `cargo miri`" , arg) ) ;
973
986
}
974
987
} else {
975
- phase_cargo_rustc ( args) ;
988
+ phase_rustc ( args, RustcPhase :: Rustdoc ) ;
976
989
}
977
990
978
991
return ;
@@ -988,17 +1001,17 @@ fn main() {
988
1001
// On top of that, we are also called as RUSTDOC, but that is just a stub currently.
989
1002
match args. next ( ) . as_deref ( ) {
990
1003
Some ( "miri" ) => phase_cargo_miri ( args) ,
991
- Some ( "rustc" ) => phase_cargo_rustc ( args) ,
1004
+ Some ( "rustc" ) => phase_rustc ( args, RustcPhase :: Build ) ,
992
1005
Some ( arg) => {
993
1006
// We have to distinguish the "runner" and "rustdoc" cases.
994
1007
// As runner, the first argument is the binary (a file that should exist, with an absolute path);
995
1008
// as rustdoc, the first argument is a flag (`--something`).
996
1009
let binary = Path :: new ( arg) ;
997
1010
if binary. exists ( ) {
998
1011
assert ! ( !arg. starts_with( "--" ) ) ; // not a flag
999
- phase_cargo_runner ( binary, args) ;
1012
+ phase_runner ( binary, args, RunnerPhase :: Cargo ) ;
1000
1013
} else if arg. starts_with ( "--" ) {
1001
- phase_cargo_rustdoc ( arg, args) ;
1014
+ phase_rustdoc ( arg, args) ;
1002
1015
} else {
1003
1016
show_error ( format ! ( "`cargo-miri` called with unexpected first argument `{}`; please only invoke this binary through `cargo miri`" , arg) ) ;
1004
1017
}
0 commit comments