@@ -413,14 +413,14 @@ path = "lib.rs"
413413 // for target crates.
414414 // We set ourselves (`cargo-miri`) instead of Miri directly to be able to patch the flags
415415 // 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`.
417417 let cargo_miri_path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
418418 if env:: var_os ( "RUSTC_STAGE" ) . is_some ( ) {
419419 command. env ( "RUSTC_REAL" , & cargo_miri_path) ;
420420 } else {
421421 command. env ( "RUSTC" , & cargo_miri_path) ;
422422 }
423- command. env ( "MIRI_BE_RUSTC " , "target " ) ;
423+ command. env ( "MIRI_CALLED_FROM_XARGO " , "1 " ) ;
424424 // Make sure there are no other wrappers or flags getting in our way
425425 // (Cc https://github.com/rust-lang/miri/issues/1421).
426426 // This is consistent with normal `cargo build` that does not apply `RUSTFLAGS`
@@ -450,21 +450,6 @@ path = "lib.rs"
450450 }
451451}
452452
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-
468453fn phase_cargo_miri ( mut args : env:: Args ) {
469454 // Check for version and help flags even when invoked as `cargo-miri`.
470455 if has_arg_flag ( "--help" ) || has_arg_flag ( "-h" ) {
@@ -598,7 +583,17 @@ fn phase_cargo_miri(mut args: env::Args) {
598583 exec ( cmd)
599584}
600585
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 ) {
602597 /// Determines if we are being invoked (as rustc) to build a crate for
603598 /// the "target" architecture, in contrast to the "host" architecture.
604599 /// 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) {
644639
645640 let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
646641 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
648643
649644 let store_json = |info : CrateRunInfo | {
650645 // Create a stub .d file to stop Cargo from "rebuilding" the crate:
@@ -669,7 +664,8 @@ fn phase_cargo_rustc(mut args: env::Args) {
669664 let runnable_crate = !print && is_runnable_crate ( ) ;
670665
671666 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 ;
673669 // This is the binary or test crate that we want to interpret under Miri.
674670 // But we cannot run it here, as cargo invoked us as a compiler -- our stdin and stdout are not
675671 // like we want them.
@@ -749,8 +745,15 @@ fn phase_cargo_rustc(mut args: env::Args) {
749745 }
750746 }
751747
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+ }
754757 } else {
755758 // For host crates or when we are printing, just forward everything.
756759 cmd. args ( args) ;
@@ -783,7 +786,15 @@ fn phase_cargo_rustc(mut args: env::Args) {
783786 }
784787}
785788
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 ) {
787798 let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
788799
789800 let file = File :: open ( & binary)
@@ -840,8 +851,8 @@ fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
840851 cmd. arg ( arg) ;
841852 }
842853 }
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 {
845856 forward_miri_sysroot ( & mut cmd) ;
846857 }
847858 // Respect `MIRIFLAGS`.
@@ -869,14 +880,17 @@ fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
869880 eprintln ! ( "[cargo-miri runner] {:?}" , cmd) ;
870881 }
871882
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+ }
876890 }
877891}
878892
879- fn phase_cargo_rustdoc ( fst_arg : & str , mut args : env:: Args ) {
893+ fn phase_rustdoc ( fst_arg : & str , mut args : env:: Args ) {
880894 let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
881895
882896 // phase_cargo_miri sets the RUSTDOC env var to ourselves, so we can't use that here;
@@ -950,15 +964,14 @@ fn main() {
950964 args. next ( ) . unwrap ( ) ;
951965
952966 // 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 ) ;
955969 return ;
956970 }
957971
958972 // The way rustdoc invokes rustc is indistuingishable from the way cargo invokes rustdoc by the
959973 // 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 ( ) {
962975 // ...however, we then also see this variable when rustdoc invokes us as the testrunner!
963976 // The runner is invoked as `$runtool ($runtool-arg)* output_file`;
964977 // since we don't specify any runtool-args, and rustdoc supplies multiple arguments to
@@ -967,12 +980,12 @@ fn main() {
967980 let arg = args. next ( ) . unwrap ( ) ;
968981 let binary = Path :: new ( & arg) ;
969982 if binary. exists ( ) {
970- phase_cargo_runner ( binary, args) ;
983+ phase_runner ( binary, args, RunnerPhase :: Rustdoc ) ;
971984 } else {
972985 show_error ( format ! ( "`cargo-miri` called with non-existing path argument `{}` in rustdoc mode; please invoke this binary through `cargo miri`" , arg) ) ;
973986 }
974987 } else {
975- phase_cargo_rustc ( args) ;
988+ phase_rustc ( args, RustcPhase :: Rustdoc ) ;
976989 }
977990
978991 return ;
@@ -988,17 +1001,17 @@ fn main() {
9881001 // On top of that, we are also called as RUSTDOC, but that is just a stub currently.
9891002 match args. next ( ) . as_deref ( ) {
9901003 Some ( "miri" ) => phase_cargo_miri ( args) ,
991- Some ( "rustc" ) => phase_cargo_rustc ( args) ,
1004+ Some ( "rustc" ) => phase_rustc ( args, RustcPhase :: Build ) ,
9921005 Some ( arg) => {
9931006 // We have to distinguish the "runner" and "rustdoc" cases.
9941007 // As runner, the first argument is the binary (a file that should exist, with an absolute path);
9951008 // as rustdoc, the first argument is a flag (`--something`).
9961009 let binary = Path :: new ( arg) ;
9971010 if binary. exists ( ) {
9981011 assert ! ( !arg. starts_with( "--" ) ) ; // not a flag
999- phase_cargo_runner ( binary, args) ;
1012+ phase_runner ( binary, args, RunnerPhase :: Cargo ) ;
10001013 } else if arg. starts_with ( "--" ) {
1001- phase_cargo_rustdoc ( arg, args) ;
1014+ phase_rustdoc ( arg, args) ;
10021015 } else {
10031016 show_error ( format ! ( "`cargo-miri` called with unexpected first argument `{}`; please only invoke this binary through `cargo miri`" , arg) ) ;
10041017 }
0 commit comments