@@ -389,26 +389,86 @@ impl Step for Miri {
389389 extra_features : Vec :: new ( ) ,
390390 } ) ;
391391 if let Some ( miri) = miri {
392- let mut cargo = tool:: prepare_tool_cargo ( builder,
393- compiler,
394- Mode :: ToolRustc ,
395- host,
396- "test" ,
397- "src/tools/miri" ,
398- SourceType :: Submodule ,
399- & [ ] ) ;
392+ // # Run `cargo miri setup`.
393+ let mut cargo = tool:: prepare_tool_cargo (
394+ builder,
395+ compiler,
396+ Mode :: ToolRustc ,
397+ host,
398+ "run" ,
399+ "src/tools/miri" ,
400+ SourceType :: Submodule ,
401+ & [ ] ,
402+ ) ;
403+ cargo
404+ . arg ( "--bin" )
405+ . arg ( "cargo-miri" )
406+ . arg ( "--" )
407+ . arg ( "miri" )
408+ . arg ( "setup" ) ;
409+
410+ // Tell `cargo miri` not to worry about the sysroot mismatch (we built with
411+ // stage1 but run with stage2).
412+ cargo. env ( "MIRI_SKIP_SYSROOT_CHECK" , "1" ) ;
413+ // Tell `cargo miri setup` where to find the sources.
414+ cargo. env ( "XARGO_RUST_SRC" , builder. src . join ( "src" ) ) ;
415+ // Make sure the libstd gets built without debug assertions.
416+ cargo. env ( "RUSTC_DEBUG_ASSERTIONS" , "false" ) ;
417+
418+ if !try_run ( builder, & mut cargo) {
419+ return ;
420+ }
421+
422+ // # Determine where Miri put its sysroot.
423+ // To this end, we run `cargo miri setup --env` and capture the output.
424+ // (We do this separately from the above so that when the setup actually
425+ // happens we get some output.)
426+ // We re-use the `cargo` from above.
427+ cargo. arg ( "--env" ) ;
428+
429+ // FIXME: Is there a way in which we can re-use the usual `run` helpers?
430+ let miri_sysroot = if builder. config . dry_run {
431+ String :: new ( )
432+ } else {
433+ let out = cargo. output ( )
434+ . expect ( "We already ran `cargo miri setup` before and that worked" ) ;
435+ assert ! ( out. status. success( ) , "`cargo miri setup` returned with non-0 exit code" ) ;
436+ // Output is "MIRI_SYSROOT=<str>\n".
437+ let stdout = String :: from_utf8 ( out. stdout )
438+ . expect ( "`cargo miri setup` stdout is not valid UTF-8" ) ;
439+ let stdout = stdout. trim ( ) ;
440+ builder. verbose ( & format ! ( "`cargo miri setup --env` returned: {:?}" , stdout) ) ;
441+ let sysroot = stdout. splitn ( 2 , '=' )
442+ . nth ( 1 ) . expect ( "`cargo miri setup` stdout did not contain '='" ) ;
443+ sysroot. to_owned ( )
444+ } ;
445+
446+ // # Run `cargo test`.
447+ let mut cargo = tool:: prepare_tool_cargo (
448+ builder,
449+ compiler,
450+ Mode :: ToolRustc ,
451+ host,
452+ "test" ,
453+ "src/tools/miri" ,
454+ SourceType :: Submodule ,
455+ & [ ] ,
456+ ) ;
400457
401458 // miri tests need to know about the stage sysroot
402- cargo. env ( "MIRI_SYSROOT" , builder . sysroot ( compiler ) ) ;
459+ cargo. env ( "MIRI_SYSROOT" , miri_sysroot ) ;
403460 cargo. env ( "RUSTC_TEST_SUITE" , builder. rustc ( compiler) ) ;
404461 cargo. env ( "RUSTC_LIB_PATH" , builder. rustc_libdir ( compiler) ) ;
405462 cargo. env ( "MIRI_PATH" , miri) ;
406463
407464 builder. add_rustc_lib_path ( compiler, & mut cargo) ;
408465
409- if try_run ( builder, & mut cargo) {
410- builder . save_toolstate ( "miri" , ToolState :: TestPass ) ;
466+ if ! try_run ( builder, & mut cargo) {
467+ return ;
411468 }
469+
470+ // # Done!
471+ builder. save_toolstate ( "miri" , ToolState :: TestPass ) ;
412472 } else {
413473 eprintln ! ( "failed to test miri: could not build" ) ;
414474 }
0 commit comments