@@ -295,8 +295,7 @@ fn setup(subcommand: MiriCommand) {
295
295
br#"
296
296
[dependencies.std]
297
297
default_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.
300
299
features = ["panic_unwind"]
301
300
302
301
[dependencies.test]
@@ -338,10 +337,14 @@ path = "lib.rs"
338
337
// because we still need bootstrap to distinguish between host and target crates.
339
338
// In that case we overwrite `RUSTC_REAL` instead which determines the rustc used
340
339
// 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" ) ;
341
344
if env:: var_os ( "RUSTC_STAGE" ) . is_some ( ) {
342
- command. env ( "RUSTC_REAL" , find_miri ( ) ) ;
345
+ command. env ( "RUSTC_REAL" , & cargo_miri_path ) ;
343
346
} else {
344
- command. env ( "RUSTC" , find_miri ( ) ) ;
347
+ command. env ( "RUSTC" , & cargo_miri_path ) ;
345
348
}
346
349
command. env ( "MIRI_BE_RUSTC" , "1" ) ;
347
350
// Make sure there are no other wrappers or flags getting in our way
@@ -370,6 +373,21 @@ path = "lib.rs"
370
373
}
371
374
}
372
375
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
+
373
391
fn phase_cargo_miri ( mut args : env:: Args ) {
374
392
// Check for version and help flags even when invoked as `cargo-miri`.
375
393
if has_arg_flag ( "--help" ) || has_arg_flag ( "-h" ) {
@@ -402,7 +420,7 @@ fn phase_cargo_miri(mut args: env::Args) {
402
420
// <https://github.com/rust-lang/miri/pull/1540#issuecomment-693553191> describes an alternative
403
421
// approach that uses `cargo check`, making that part easier but target and binary handling
404
422
// 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" ) ;
406
424
let cargo_cmd = match subcommand {
407
425
MiriCommand :: Test => "test" ,
408
426
MiriCommand :: Run => "run" ,
@@ -470,22 +488,22 @@ fn phase_cargo_miri(mut args: env::Args) {
470
488
if env:: var_os ( "RUSTC_WRAPPER" ) . is_some ( ) {
471
489
println ! ( "WARNING: Ignoring `RUSTC_WRAPPER` environment variable, Miri does not support wrapping." ) ;
472
490
}
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) ;
477
492
478
493
// Set the runner for the current target to us as well, so we can interpret the binaries.
479
494
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 ) ;
481
496
482
497
// 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 ) ;
484
499
485
500
// Run cargo.
486
501
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) ;
488
505
eprintln ! ( "[cargo-miri miri] {:?}" , cmd) ;
506
+ cmd. env ( "MIRI_VERBOSE" , "" ) ; // This makes the other phases verbose.
489
507
}
490
508
exec ( cmd)
491
509
}
@@ -699,6 +717,12 @@ fn main() {
699
717
// Skip binary name.
700
718
args. next ( ) . unwrap ( ) ;
701
719
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
+
702
726
// Dispatch to `cargo-miri` phase. There are three phases:
703
727
// - When we are called via `cargo miri`, we run as the frontend and invoke the underlying
704
728
// cargo. We set RUSTC_WRAPPER and CARGO_TARGET_RUNNER to ourselves.
0 commit comments