@@ -8,6 +8,8 @@ use std::path::{Path, PathBuf};
88use std:: process:: Command ;
99use std:: ffi:: OsString ;
1010
11+ use rustc_version:: VersionMeta ;
12+
1113const XARGO_MIN_VERSION : ( u32 , u32 , u32 ) = ( 0 , 3 , 20 ) ;
1214
1315const CARGO_MIRI_HELP : & str = r#"Interprets bin crates and tests in Miri
@@ -97,6 +99,10 @@ fn miri() -> Command {
9799 Command :: new ( find_miri ( ) )
98100}
99101
102+ fn version_info ( ) -> VersionMeta {
103+ VersionMeta :: for_command ( miri ( ) ) . expect ( "failed to determine underlying rustc version of Miri" )
104+ }
105+
100106fn cargo ( ) -> Command {
101107 Command :: new ( env:: var_os ( "CARGO" ) . unwrap_or_else ( || OsString :: from ( "cargo" ) ) )
102108}
@@ -105,10 +111,6 @@ fn xargo_check() -> Command {
105111 Command :: new ( env:: var_os ( "XARGO_CHECK" ) . unwrap_or_else ( || OsString :: from ( "xargo-check" ) ) )
106112}
107113
108- fn rustc ( ) -> Command {
109- Command :: new ( env:: var_os ( "RUSTC" ) . unwrap_or_else ( || OsString :: from ( "rustc" ) ) )
110- }
111-
112114fn list_targets ( ) -> impl Iterator < Item = cargo_metadata:: Target > {
113115 // We need to get the manifest, and then the metadata, to enumerate targets.
114116 let manifest_path =
@@ -153,55 +155,6 @@ fn list_targets() -> impl Iterator<Item = cargo_metadata::Target> {
153155 package. targets . into_iter ( )
154156}
155157
156- /// Make sure that the `miri` and `rustc` binary are from the same sysroot.
157- /// This can be violated e.g. when miri is locally built and installed with a different
158- /// toolchain than what is used when `cargo miri` is run.
159- fn test_sysroot_consistency ( ) {
160- fn get_sysroot ( mut cmd : Command ) -> PathBuf {
161- let out = cmd
162- . arg ( "--print" )
163- . arg ( "sysroot" )
164- . output ( )
165- . expect ( "Failed to run rustc to get sysroot info" ) ;
166- let stdout = String :: from_utf8 ( out. stdout ) . expect ( "stdout is not valid UTF-8" ) ;
167- let stderr = String :: from_utf8 ( out. stderr ) . expect ( "stderr is not valid UTF-8" ) ;
168- assert ! (
169- out. status. success( ) ,
170- "Bad status code {} when getting sysroot info via {:?}.\n stdout:\n {}\n stderr:\n {}" ,
171- out. status,
172- cmd,
173- stdout,
174- stderr,
175- ) ;
176- let stdout = stdout. trim ( ) ;
177- PathBuf :: from ( stdout)
178- . canonicalize ( )
179- . unwrap_or_else ( |_| panic ! ( "Failed to canonicalize sysroot: {}" , stdout) )
180- }
181-
182- // Do not check sysroots if we got built as part of a Rust distribution.
183- // During `bootstrap`, the sysroot does not match anyway, and then some distros
184- // play symlink tricks so the sysroots may be different even for the final stage
185- // (see <https://github.com/mozilla/nixpkgs-mozilla/issues/198>).
186- if option_env ! ( "RUSTC_STAGE" ) . is_some ( ) {
187- return ;
188- }
189-
190- let rustc_sysroot = get_sysroot ( rustc ( ) ) ;
191- let miri_sysroot = get_sysroot ( miri ( ) ) ;
192-
193- if rustc_sysroot != miri_sysroot {
194- show_error ( format ! (
195- "miri was built for a different sysroot than the rustc in your current toolchain.\n \
196- Make sure you use the same toolchain to run miri that you used to build it!\n \
197- rustc sysroot: `{}`\n \
198- miri sysroot: `{}`",
199- rustc_sysroot. display( ) ,
200- miri_sysroot. display( )
201- ) ) ;
202- }
203- }
204-
205158fn xargo_version ( ) -> Option < ( u32 , u32 , u32 ) > {
206159 let out = xargo_check ( ) . arg ( "--version" ) . output ( ) . ok ( ) ?;
207160 if !out. status . success ( ) {
@@ -300,10 +253,10 @@ fn setup(subcommand: MiriCommand) {
300253 Some ( val) => PathBuf :: from ( val) ,
301254 None => {
302255 // Check for `rust-src` rustup component.
303- let sysroot = rustc ( )
256+ let sysroot = miri ( )
304257 . args ( & [ "--print" , "sysroot" ] )
305258 . output ( )
306- . expect ( "failed to get rustc sysroot" )
259+ . expect ( "failed to determine sysroot" )
307260 . stdout ;
308261 let sysroot = std:: str:: from_utf8 ( & sysroot) . unwrap ( ) ;
309262 let sysroot = Path :: new ( sysroot. trim_end_matches ( '\n' ) ) ;
@@ -316,7 +269,7 @@ fn setup(subcommand: MiriCommand) {
316269 ask_to_run (
317270 cmd,
318271 ask_user,
319- "install the rustc -src component for the selected toolchain" ,
272+ "install the `rust -src` component for the selected toolchain" ,
320273 ) ;
321274 }
322275 rustup_src
@@ -368,7 +321,7 @@ path = "lib.rs"
368321
369322 // Determine architectures.
370323 // We always need to set a target so rustc bootstrap can tell apart host from target crates.
371- let host = rustc_version :: version_meta ( ) . unwrap ( ) . host ;
324+ let host = version_info ( ) . host ;
372325 let target = get_arg_flag_value ( "--target" ) ;
373326 let target = target. as_ref ( ) . unwrap_or ( & host) ;
374327 // Now invoke xargo.
@@ -389,7 +342,6 @@ path = "lib.rs"
389342 command. env ( "RUSTC" , find_miri ( ) ) ;
390343 }
391344 command. env ( "MIRI_BE_RUSTC" , "1" ) ;
392- command. env ( "RUSTFLAGS" , miri:: miri_default_args ( ) . join ( " " ) ) ;
393345 // Finally run it!
394346 if command. status ( ) . expect ( "failed to run xargo" ) . success ( ) . not ( ) {
395347 show_error ( format ! ( "Failed to run xargo" ) ) ;
@@ -424,9 +376,6 @@ fn in_cargo_miri() {
424376 } ;
425377 let verbose = has_arg_flag ( "-v" ) ;
426378
427- // Some basic sanity checks
428- test_sysroot_consistency ( ) ;
429-
430379 // We always setup.
431380 setup ( subcommand) ;
432381 if subcommand == MiriCommand :: Setup {
@@ -478,7 +427,7 @@ fn in_cargo_miri() {
478427 if get_arg_flag_value ( "--target" ) . is_none ( ) {
479428 // When no `--target` is given, default to the host.
480429 cmd. arg ( "--target" ) ;
481- cmd. arg ( rustc_version :: version_meta ( ) . unwrap ( ) . host ) ;
430+ cmd. arg ( version_info ( ) . host ) ;
482431 }
483432
484433 // Serialize the remaining args into a special environemt variable.
@@ -540,51 +489,46 @@ fn inside_cargo_rustc() {
540489 let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
541490 let target_crate = is_target_crate ( ) ;
542491
543- // Figure out which arguments we need to pass.
544- let mut args: Vec < String > = std:: env:: args ( ) . skip ( 2 ) . collect ( ) ; // skip `cargo-miri rustc`
545- // We make sure to only specify our custom Xargo sysroot and
546- // other args for target crates - that is, crates which are ultimately
547- // going to get interpreted by Miri.
492+ let mut cmd = miri ( ) ;
493+ // Forward arguments.
494+ cmd. args ( std:: env:: args ( ) . skip ( 2 ) ) ; // skip `cargo-miri rustc`
495+
496+ // We make sure to only specify our custom Xargo sysroot for target crates - that is,
497+ // crates which are ultimately going to get interpreted by Miri.
548498 if target_crate {
549- // FIXME: breaks for non-UTF-8 sysroots (use `var_os` instead).
550499 let sysroot =
551- std:: env:: var ( "MIRI_SYSROOT" ) . expect ( "The wrapper should have set MIRI_SYSROOT" ) ;
552- args. push ( "--sysroot" . to_owned ( ) ) ;
553- args. push ( sysroot) ;
554- args. splice ( 0 ..0 , miri:: miri_default_args ( ) . iter ( ) . map ( ToString :: to_string) ) ;
500+ env:: var_os ( "MIRI_SYSROOT" ) . expect ( "The wrapper should have set MIRI_SYSROOT" ) ;
501+ cmd. arg ( "--sysroot" ) ;
502+ cmd. arg ( sysroot) ;
555503 }
556504
557- // Figure out the binary we need to call. If this is a runnable target crate, we want to call
558- // Miri to start interpretation; otherwise we want to call rustc to build the crate as usual.
559- let mut command = if target_crate && is_runnable_crate ( ) {
560- // This is the 'target crate' - the binary or test crate that
561- // we want to interpret under Miri. We deserialize the user-provided arguments
562- // from the special environment variable "MIRI_ARGS", and feed them
563- // to the 'miri' binary.
505+ // If this is a runnable target crate, we want Miri to start interpretation;
506+ // otherwise we want Miri to behave like rustc and build the crate as usual.
507+ if target_crate && is_runnable_crate ( ) {
508+ // This is the binary or test crate that we want to interpret under Miri.
509+ // We deserialize the arguments that are meant for Miri from the special environment
510+ // variable "MIRI_ARGS", and feed them to the 'miri' binary.
564511 //
565512 // `env::var` is okay here, well-formed JSON is always UTF-8.
566513 let magic = std:: env:: var ( "MIRI_ARGS" ) . expect ( "missing MIRI_ARGS" ) ;
567- let mut user_args : Vec < String > =
514+ let miri_args : Vec < String > =
568515 serde_json:: from_str ( & magic) . expect ( "failed to deserialize MIRI_ARGS" ) ;
569- args. append ( & mut user_args) ;
570- // Run this in Miri.
571- miri ( )
516+ cmd. args ( miri_args) ;
572517 } else {
573- rustc ( )
518+ // We want to compile, not interpret.
519+ cmd. env ( "MIRI_BE_RUSTC" , "1" ) ;
574520 } ;
575521
576522 // Run it.
577- command. args ( & args) ;
578523 if verbose {
579- eprintln ! ( "+ {:?}" , command ) ;
524+ eprintln ! ( "+ {:?}" , cmd ) ;
580525 }
581-
582- match command. status ( ) {
526+ match cmd. status ( ) {
583527 Ok ( exit) =>
584528 if !exit. success ( ) {
585529 std:: process:: exit ( exit. code ( ) . unwrap_or ( 42 ) ) ;
586530 } ,
587- Err ( e) => panic ! ( "error running {:?}:\n {:?}" , command , e) ,
531+ Err ( e) => panic ! ( "error running {:?}:\n {:?}" , cmd , e) ,
588532 }
589533}
590534
@@ -609,6 +553,6 @@ fn main() {
609553 // dependencies get dispatched to `rustc`, the final test/binary to `miri`.
610554 inside_cargo_rustc ( ) ;
611555 } else {
612- show_error ( format ! ( "must be called with either `miri` or `rustc` as first argument." ) )
556+ show_error ( format ! ( "`cargo-miri` must be called with either `miri` or `rustc` as first argument." ) )
613557 }
614558}
0 commit comments