@@ -295,8 +295,7 @@ fn setup(subcommand: MiriCommand) {
295295 br#"
296296[dependencies.std]
297297default_features = false
298- # We need the `panic_unwind` feature because we use the `unwind` panic strategy.
299- # Using `abort` works for libstd, but then libtest will not compile.
298+ # We support unwinding, so enable that panic runtime.
300299features = ["panic_unwind"]
301300
302301[dependencies.test]
@@ -338,10 +337,14 @@ path = "lib.rs"
338337 // because we still need bootstrap to distinguish between host and target crates.
339338 // In that case we overwrite `RUSTC_REAL` instead which determines the rustc used
340339 // for target crates.
340+ // We set ourselves (`cargo-miri`) instead of Miri directly to be able to patch the flags
341+ // for `libpanic_abort` (usually this is done by bootstrap but we have to do it ourselves).
342+ // The `MIRI_BE_RUSTC` will mean we dispatch to `phase_setup_rustc`.
343+ let cargo_miri_path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
341344 if env:: var_os ( "RUSTC_STAGE" ) . is_some ( ) {
342- command. env ( "RUSTC_REAL" , find_miri ( ) ) ;
345+ command. env ( "RUSTC_REAL" , & cargo_miri_path ) ;
343346 } else {
344- command. env ( "RUSTC" , find_miri ( ) ) ;
347+ command. env ( "RUSTC" , & cargo_miri_path ) ;
345348 }
346349 command. env ( "MIRI_BE_RUSTC" , "1" ) ;
347350 // Make sure there are no other wrappers or flags getting in our way
@@ -370,6 +373,21 @@ path = "lib.rs"
370373 }
371374}
372375
376+ fn phase_setup_rustc ( args : env:: Args ) {
377+ // Mostly we just forward everything.
378+ // `MIRI_BE_RUST` is already set.
379+ let mut cmd = miri ( ) ;
380+ cmd. args ( args) ;
381+
382+ // Patch the panic runtime for `libpanic_abort` (mirroring what bootstrap usually does).
383+ if get_arg_flag_value ( "--crate-name" ) . as_deref ( ) == Some ( "panic_abort" ) {
384+ cmd. arg ( "-C" ) . arg ( "panic=abort" ) ;
385+ }
386+
387+ // Run it!
388+ exec ( cmd) ;
389+ }
390+
373391fn phase_cargo_miri ( mut args : env:: Args ) {
374392 // Check for version and help flags even when invoked as `cargo-miri`.
375393 if has_arg_flag ( "--help" ) || has_arg_flag ( "-h" ) {
@@ -402,7 +420,7 @@ fn phase_cargo_miri(mut args: env::Args) {
402420 // <https://github.com/rust-lang/miri/pull/1540#issuecomment-693553191> describes an alternative
403421 // approach that uses `cargo check`, making that part easier but target and binary handling
404422 // harder.
405- let miri_path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
423+ let cargo_miri_path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
406424 let cargo_cmd = match subcommand {
407425 MiriCommand :: Test => "test" ,
408426 MiriCommand :: Run => "run" ,
@@ -470,22 +488,22 @@ fn phase_cargo_miri(mut args: env::Args) {
470488 if env:: var_os ( "RUSTC_WRAPPER" ) . is_some ( ) {
471489 println ! ( "WARNING: Ignoring `RUSTC_WRAPPER` environment variable, Miri does not support wrapping." ) ;
472490 }
473- cmd. env ( "RUSTC_WRAPPER" , & miri_path) ;
474- if verbose {
475- eprintln ! ( "+ RUSTC_WRAPPER={:?}" , miri_path) ;
476- }
491+ cmd. env ( "RUSTC_WRAPPER" , & cargo_miri_path) ;
477492
478493 // Set the runner for the current target to us as well, so we can interpret the binaries.
479494 let runner_env_name = format ! ( "CARGO_TARGET_{}_RUNNER" , target. to_uppercase( ) . replace( '-' , "_" ) ) ;
480- cmd. env ( runner_env_name, & miri_path ) ;
495+ cmd. env ( & runner_env_name, & cargo_miri_path ) ;
481496
482497 // Set rustdoc to us as well, so we can make it do nothing (see issue #584).
483- cmd. env ( "RUSTDOC" , & miri_path ) ;
498+ cmd. env ( "RUSTDOC" , & cargo_miri_path ) ;
484499
485500 // Run cargo.
486501 if verbose {
487- cmd. env ( "MIRI_VERBOSE" , "" ) ; // This makes the other phases verbose.
502+ eprintln ! ( "[cargo-miri miri] RUSTC_WRAPPER={:?}" , cargo_miri_path) ;
503+ eprintln ! ( "[cargo-miri miri] {}={:?}" , runner_env_name, cargo_miri_path) ;
504+ eprintln ! ( "[cargo-miri miri] RUSTDOC={:?}" , cargo_miri_path) ;
488505 eprintln ! ( "[cargo-miri miri] {:?}" , cmd) ;
506+ cmd. env ( "MIRI_VERBOSE" , "" ) ; // This makes the other phases verbose.
489507 }
490508 exec ( cmd)
491509}
@@ -699,6 +717,12 @@ fn main() {
699717 // Skip binary name.
700718 args. next ( ) . unwrap ( ) ;
701719
720+ // Dispatch running as part of sysroot compilation.
721+ if env:: var_os ( "MIRI_BE_RUSTC" ) . is_some ( ) {
722+ phase_setup_rustc ( args) ;
723+ return ;
724+ }
725+
702726 // Dispatch to `cargo-miri` phase. There are three phases:
703727 // - When we are called via `cargo miri`, we run as the frontend and invoke the underlying
704728 // cargo. We set RUSTC_WRAPPER and CARGO_TARGET_RUNNER to ourselves.
0 commit comments