@@ -179,18 +179,27 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
179
179
) ;
180
180
}
181
181
cmd. env ( "RUSTC_WRAPPER" , & cargo_miri_path) ;
182
+ // There's also RUSTC_WORKSPACE_WRAPPER, which gets in the way of our own wrapping.
183
+ if env:: var_os ( "RUSTC_WORKSPACE_WRAPPER" ) . is_some ( ) {
184
+ println ! (
185
+ "WARNING: Ignoring `RUSTC_WORKSPACE_WRAPPER` environment variable, Miri does not support wrapping."
186
+ ) ;
187
+ }
188
+ cmd. env_remove ( "RUSTC_WORKSPACE_WRAPPER" ) ;
182
189
// We are going to invoke `MIRI` for everything, not `RUSTC`.
183
190
if env:: var_os ( "RUSTC" ) . is_some ( ) && env:: var_os ( "MIRI" ) . is_none ( ) {
184
191
println ! (
185
192
"WARNING: Ignoring `RUSTC` environment variable; set `MIRI` if you want to control the binary used as the driver."
186
193
) ;
187
194
}
188
- // Build scripts (and also cargo: https://github.com/rust-lang/cargo/issues/10885) will invoke
189
- // `rustc` even when `RUSTC_WRAPPER` is set. To make sure everything is coherent, we want that
190
- // to be the Miri driver, but acting as rustc, on the target level. (Target, rather than host,
191
- // is needed for cross-interpretation situations.) This is not a perfect emulation of real rustc
192
- // (it might be unable to produce binaries since the sysroot is check-only), but it's as close
193
- // as we can get, and it's good enough for autocfg.
195
+ // Ideally we would set RUSTC to some non-existent path, so we can be sure our wrapping is
196
+ // always applied. However, buggy build scripts (https://github.com/eyre-rs/eyre/issues/84) and
197
+ // also cargo (https://github.com/rust-lang/cargo/issues/10885) will invoke `rustc` even when
198
+ // `RUSTC_WRAPPER` is set, bypassing the wrapper. To make sure everything is coherent, we want
199
+ // that to be the Miri driver, but acting as rustc, on the target level. (Target, rather than
200
+ // host, is needed for cross-interpretation situations.) This is not a perfect emulation of real
201
+ // rustc (it might be unable to produce binaries since the sysroot is check-only), but it's as
202
+ // close as we can get, and it's good enough for autocfg.
194
203
//
195
204
// In `main`, we need the value of `RUSTC` to distinguish RUSTC_WRAPPER invocations from rustdoc
196
205
// or TARGET_RUNNER invocations, so we canonicalize it here to make it exceedingly unlikely that
@@ -247,6 +256,16 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
247
256
/// Cargo does not give us this information directly, so we need to check
248
257
/// various command-line flags.
249
258
fn is_runnable_crate ( ) -> bool {
259
+ // Determine whether this is cargo invoking rustc to get some infos. Ideally we'd check "is
260
+ // there a filename passed to rustc", but that's very hard as we would have to know whether
261
+ // e.g. `--print foo` is a booolean flag `--print` followed by filename `foo` or equivalent
262
+ // to `--print=foo`. So instead we use this more fragile approach of detecting the presence
263
+ // of a "query" flag rather than the absence of a filename.
264
+ let info_query = get_arg_flag_value ( "--print" ) . is_some ( ) || has_arg_flag ( "-vV" ) ;
265
+ if info_query {
266
+ // Nothing to run.
267
+ return false ;
268
+ }
250
269
let is_bin = get_arg_flag_value ( "--crate-type" ) . as_deref ( ) . unwrap_or ( "bin" ) == "bin" ;
251
270
let is_test = has_arg_flag ( "--test" ) ;
252
271
is_bin || is_test
@@ -285,16 +304,9 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
285
304
}
286
305
}
287
306
288
- // phase_cargo_miri set `MIRI_BE_RUSTC` for when build scripts directly invoke the driver;
289
- // however, if we get called back by cargo here, we'll carefully compute the right flags
290
- // ourselves, so we first un-do what the earlier phase did.
291
- env:: remove_var ( "MIRI_BE_RUSTC" ) ;
292
-
293
307
let verbose = std:: env:: var ( "MIRI_VERBOSE" )
294
308
. map_or ( 0 , |verbose| verbose. parse ( ) . expect ( "verbosity flag must be an integer" ) ) ;
295
309
let target_crate = is_target_crate ( ) ;
296
- // Determine whether this is cargo invoking rustc to get some infos.
297
- let info_query = get_arg_flag_value ( "--print" ) . is_some ( ) || has_arg_flag ( "-vV" ) ;
298
310
299
311
let store_json = |info : CrateRunInfo | {
300
312
if get_arg_flag_value ( "--emit" ) . unwrap_or_default ( ) . split ( ',' ) . any ( |e| e == "dep-info" ) {
@@ -321,7 +333,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
321
333
}
322
334
} ;
323
335
324
- let runnable_crate = !info_query && is_runnable_crate ( ) ;
336
+ let runnable_crate = is_runnable_crate ( ) ;
325
337
326
338
if runnable_crate && target_crate {
327
339
assert ! (
@@ -395,7 +407,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
395
407
let mut emit_link_hack = false ;
396
408
// Arguments are treated very differently depending on whether this crate is
397
409
// for interpretation by Miri, or for use by a build script / proc macro.
398
- if !info_query && target_crate {
410
+ if target_crate {
399
411
// Forward arguments, but remove "link" from "--emit" to make this a check-only build.
400
412
let emit_flag = "--emit" ;
401
413
while let Some ( arg) = args. next ( ) {
@@ -429,17 +441,14 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
429
441
cmd. arg ( "-C" ) . arg ( "panic=abort" ) ;
430
442
}
431
443
} else {
432
- // For host crates (but not when we are just printing some info),
433
- // we might still have to set the sysroot.
434
- if !info_query {
435
- // When we're running `cargo-miri` from `x.py` we need to pass the sysroot explicitly
436
- // due to bootstrap complications.
437
- if let Some ( sysroot) = std:: env:: var_os ( "MIRI_HOST_SYSROOT" ) {
438
- cmd. arg ( "--sysroot" ) . arg ( sysroot) ;
439
- }
444
+ // This is a host crate.
445
+ // When we're running `cargo-miri` from `x.py` we need to pass the sysroot explicitly
446
+ // due to bootstrap complications.
447
+ if let Some ( sysroot) = std:: env:: var_os ( "MIRI_HOST_SYSROOT" ) {
448
+ cmd. arg ( "--sysroot" ) . arg ( sysroot) ;
440
449
}
441
450
442
- // For host crates or when we are printing, just forward everything.
451
+ // Forward everything.
443
452
cmd. args ( args) ;
444
453
}
445
454
@@ -451,9 +460,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
451
460
452
461
// Run it.
453
462
if verbose > 0 {
454
- eprintln ! (
455
- "[cargo-miri rustc] target_crate={target_crate} runnable_crate={runnable_crate} info_query={info_query}"
456
- ) ;
463
+ eprintln ! ( "[cargo-miri rustc] target_crate={target_crate} runnable_crate={runnable_crate}" ) ;
457
464
}
458
465
459
466
// Create a stub .rlib file if "link" was requested by cargo.
@@ -480,11 +487,6 @@ pub enum RunnerPhase {
480
487
}
481
488
482
489
pub fn phase_runner ( mut binary_args : impl Iterator < Item = String > , phase : RunnerPhase ) {
483
- // phase_cargo_miri set `MIRI_BE_RUSTC` for when build scripts directly invoke the driver;
484
- // however, if we get called back by cargo here, we'll carefully compute the right flags
485
- // ourselves, so we first un-do what the earlier phase did.
486
- env:: remove_var ( "MIRI_BE_RUSTC" ) ;
487
-
488
490
let verbose = std:: env:: var ( "MIRI_VERBOSE" )
489
491
. map_or ( 0 , |verbose| verbose. parse ( ) . expect ( "verbosity flag must be an integer" ) ) ;
490
492
@@ -542,15 +544,13 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
542
544
// but when we run here, cargo does not interpret the JSON any more. `--json`
543
545
// then also needs to be dropped.
544
546
let mut args = info. args . into_iter ( ) ;
545
- let error_format_flag = "--error-format" ;
546
- let json_flag = "--json" ;
547
547
while let Some ( arg) = args. next ( ) {
548
548
if arg == "--extern" {
549
549
forward_patched_extern_arg ( & mut args, & mut cmd) ;
550
- } else if let Some ( suffix) = arg. strip_prefix ( error_format_flag ) {
550
+ } else if let Some ( suffix) = arg. strip_prefix ( "--error-format" ) {
551
551
assert ! ( suffix. starts_with( '=' ) ) ;
552
552
// Drop this argument.
553
- } else if let Some ( suffix) = arg. strip_prefix ( json_flag ) {
553
+ } else if let Some ( suffix) = arg. strip_prefix ( "--json" ) {
554
554
assert ! ( suffix. starts_with( '=' ) ) ;
555
555
// Drop this argument.
556
556
} else {
@@ -589,13 +589,11 @@ pub fn phase_rustdoc(mut args: impl Iterator<Item = String>) {
589
589
let rustdoc = env:: var ( "MIRI_ORIG_RUSTDOC" ) . unwrap_or ( "rustdoc" . to_string ( ) ) ;
590
590
let mut cmd = Command :: new ( rustdoc) ;
591
591
592
- let extern_flag = "--extern" ;
593
- let runtool_flag = "--runtool" ;
594
592
while let Some ( arg) = args. next ( ) {
595
- if arg == extern_flag {
593
+ if arg == "--extern" {
596
594
// Patch --extern arguments to use *.rmeta files, since phase_cargo_rustc only creates stub *.rlib files.
597
595
forward_patched_extern_arg ( & mut args, & mut cmd) ;
598
- } else if arg == runtool_flag {
596
+ } else if arg == "--runtool" {
599
597
// An existing --runtool flag indicates cargo is running in cross-target mode, which we don't support.
600
598
// Note that this is only passed when cargo is run with the unstable -Zdoctest-xcompile flag;
601
599
// otherwise, we won't be called as rustdoc at all.
0 commit comments