@@ -493,8 +493,6 @@ impl Step for RustDemangler {
493
493
494
494
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
495
495
pub struct Miri {
496
- stage: u32,
497
- host: TargetSelection,
498
496
target: TargetSelection,
499
497
}
500
498
@@ -503,41 +501,26 @@ impl Miri {
503
501
pub fn build_miri_sysroot(
504
502
builder: &Builder<'_>,
505
503
compiler: Compiler,
506
- miri: &Path,
507
504
target: TargetSelection,
508
505
) -> String {
509
506
let miri_sysroot = builder.out.join(compiler.host.triple).join("miri-sysroot");
510
- let mut cargo = tool::prepare_tool_cargo (
507
+ let mut cargo = builder::Cargo::new (
511
508
builder,
512
509
compiler,
513
- Mode::ToolRustc,
514
- compiler.host,
515
- "run",
516
- "src/tools/miri/cargo-miri",
517
- SourceType::InTree,
518
- &[],
510
+ Mode::Std,
511
+ SourceType::Submodule,
512
+ target,
513
+ "miri-setup",
519
514
);
520
- cargo.add_rustc_lib_path(builder);
521
- cargo.arg("--").arg("miri").arg("setup");
522
- cargo.arg("--target").arg(target.rustc_target_arg());
523
515
524
516
// Tell `cargo miri setup` where to find the sources.
525
517
cargo.env("MIRI_LIB_SRC", builder.src.join("library"));
526
- // Tell it where to find Miri.
527
- cargo.env("MIRI", miri);
528
518
// Tell it where to put the sysroot.
529
519
cargo.env("MIRI_SYSROOT", &miri_sysroot);
530
- // Debug things.
531
- cargo.env("RUST_BACKTRACE", "1");
532
520
533
521
let mut cargo = Command::from(cargo);
534
- let _guard = builder.msg(
535
- Kind::Build,
536
- compiler.stage + 1,
537
- "miri sysroot",
538
- compiler.host,
539
- compiler.host,
540
- );
522
+ let _guard =
523
+ builder.msg(Kind::Build, compiler.stage, "miri sysroot", compiler.host, target);
541
524
builder.run(&mut cargo);
542
525
543
526
// # Determine where Miri put its sysroot.
@@ -574,68 +557,75 @@ impl Step for Miri {
574
557
}
575
558
576
559
fn make_run(run: RunConfig<'_>) {
577
- run.builder.ensure(Miri {
578
- stage: run.builder.top_stage,
579
- host: run.build_triple(),
580
- target: run.target,
581
- });
560
+ run.builder.ensure(Miri { target: run.target });
582
561
}
583
562
584
563
/// Runs `cargo test` for miri.
585
564
fn run(self, builder: &Builder<'_>) {
586
- let stage = self.stage;
587
- let host = self.host;
565
+ let host = builder.build.build;
588
566
let target = self.target;
589
- let compiler = builder.compiler(stage, host);
590
- // We need the stdlib for the *next* stage, as it was built with this compiler that also built Miri.
591
- // Except if we are at stage 2, the bootstrap loop is complete and we can stick with our current stage.
592
- let compiler_std = builder.compiler(if stage < 2 { stage + 1 } else { stage }, host);
593
-
594
- let miri =
595
- builder.ensure(tool::Miri { compiler, target: self.host, extra_features: Vec::new() });
596
- let _cargo_miri = builder.ensure(tool::CargoMiri {
597
- compiler,
598
- target: self.host,
567
+ let stage = builder.top_stage;
568
+ if stage == 0 {
569
+ eprintln!("miri cannot be tested at stage 0");
570
+ std::process::exit(1);
571
+ }
572
+
573
+ // This compiler runs on the host, we'll just use it for the target.
574
+ let target_compiler = builder.compiler(stage, host);
575
+ // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise
576
+ // we'd have stageN/bin/rustc and stageN/bin/rustdoc be effectively different stage
577
+ // compilers, which isn't what we want. Rustdoc should be linked in the same way as the
578
+ // rustc compiler it's paired with, so it must be built with the previous stage compiler.
579
+ let host_compiler = builder.compiler(stage - 1, host);
580
+
581
+ // Build our tools.
582
+ let miri = builder.ensure(tool::Miri {
583
+ compiler: host_compiler,
584
+ target: host,
585
+ extra_features: Vec::new(),
586
+ });
587
+ // the ui tests also assume cargo-miri has been built
588
+ builder.ensure(tool::CargoMiri {
589
+ compiler: host_compiler,
590
+ target: host,
599
591
extra_features: Vec::new(),
600
592
});
601
- // The stdlib we need might be at a different stage. And just asking for the
602
- // sysroot does not seem to populate it, so we do that first .
603
- builder.ensure(compile::Std::new(compiler_std, host));
604
- let sysroot = builder.sysroot(compiler_std );
605
- // We also need a Miri sysroot.
606
- let miri_sysroot = Miri::build_miri_sysroot( builder, compiler, &miri, target );
593
+
594
+ // We also need sysroots, for Miri and for the host (the latter for build scripts) .
595
+ // This is for the tests so everything is done with the target compiler.
596
+ let miri_sysroot = Miri::build_miri_sysroot(builder, target_compiler, target );
597
+ builder.ensure(compile::Std::new(target_compiler, host));
598
+ let sysroot = builder.sysroot(target_compiler );
607
599
608
600
// # Run `cargo test`.
601
+ // This is with the Miri crate, so it uses the host compiler.
609
602
let mut cargo = tool::prepare_tool_cargo(
610
603
builder,
611
- compiler ,
604
+ host_compiler ,
612
605
Mode::ToolRustc,
613
606
host,
614
607
"test",
615
608
"src/tools/miri",
616
609
SourceType::InTree,
617
610
&[],
618
611
);
619
- let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "miri", host, target);
620
612
621
613
cargo.add_rustc_lib_path(builder);
622
614
615
+ // We can NOT use `run_cargo_test` since Miri's integration tests do not use the usual test
616
+ // harness and therefore do not understand the flags added by `add_flags_and_try_run_test`.
617
+ let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", host_compiler, host, builder);
618
+
623
619
// miri tests need to know about the stage sysroot
624
620
cargo.env("MIRI_SYSROOT", &miri_sysroot);
625
621
cargo.env("MIRI_HOST_SYSROOT", &sysroot);
626
622
cargo.env("MIRI", &miri);
627
- if builder.config.locked_deps {
628
- // enforce lockfiles
629
- cargo.env("CARGO_EXTRA_FLAGS", "--locked");
630
- }
631
623
632
624
// Set the target.
633
625
cargo.env("MIRI_TEST_TARGET", target.rustc_target_arg());
634
626
635
- // This can NOT be `run_cargo_test` since the Miri test runner
636
- // does not understand the flags added by `add_flags_and_try_run_test`.
637
- let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", compiler, target, builder);
638
627
{
628
+ let _guard = builder.msg_sysroot_tool(Kind::Test, stage, "miri", host, target);
639
629
let _time = helpers::timeit(builder);
640
630
builder.run(&mut cargo);
641
631
}
@@ -650,8 +640,14 @@ impl Step for Miri {
650
640
// Optimizations can change error locations and remove UB so don't run `fail` tests.
651
641
cargo.args(["tests/pass", "tests/panic"]);
652
642
653
- let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", compiler, target, builder);
654
643
{
644
+ let _guard = builder.msg_sysroot_tool(
645
+ Kind::Test,
646
+ stage,
647
+ "miri (mir-opt-level 4)",
648
+ host,
649
+ target,
650
+ );
655
651
let _time = helpers::timeit(builder);
656
652
builder.run(&mut cargo);
657
653
}
@@ -660,42 +656,40 @@ impl Step for Miri {
660
656
// # Run `cargo miri test`.
661
657
// This is just a smoke test (Miri's own CI invokes this in a bunch of different ways and ensures
662
658
// that we get the desired output), but that is sufficient to make sure that the libtest harness
663
- // itself executes properly under Miri.
659
+ // itself executes properly under Miri, and that all the logic in `cargo-miri` does not explode.
660
+ // This is running the build `cargo-miri` for the given target, so we need the target compiler.
664
661
let mut cargo = tool::prepare_tool_cargo(
665
662
builder,
666
- compiler ,
667
- Mode::ToolRustc,
668
- host ,
669
- "run ",
670
- "src/tools/miri/cargo-miri",
663
+ target_compiler ,
664
+ Mode::ToolStd, // it's unclear what to use here, we're not building anything just doing a smoke test!
665
+ target ,
666
+ "miri-test ",
667
+ "src/tools/miri/test- cargo-miri",
671
668
SourceType::Submodule,
672
669
&[],
673
670
);
674
- cargo.add_rustc_lib_path(builder);
675
- cargo.arg("--").arg("miri").arg("test");
676
- if builder.config.locked_deps {
677
- cargo.arg("--locked");
678
- }
679
- cargo
680
- .arg("--manifest-path")
681
- .arg(builder.src.join("src/tools/miri/test-cargo-miri/Cargo.toml"));
682
- cargo.arg("--target").arg(target.rustc_target_arg());
683
- cargo.arg("--").args(builder.config.test_args());
684
671
685
- // `prepare_tool_cargo` sets RUSTDOC to the bootstrap wrapper and RUSTDOC_REAL to a dummy path as this is a "run", not a "test".
686
- // Also, we want the rustdoc from the "next" stage for the same reason that we build a std from the next stage.
687
- // So let's just set that here, and bypass bootstrap's RUSTDOC (just like cargo-miri already ignores bootstrap's RUSTC_WRAPPER).
688
- cargo.env("RUSTDOC", builder.rustdoc(compiler_std));
672
+ // We're not using `prepare_cargo_test` so we have to do this ourselves.
673
+ // (We're not using that as the test-cargo-miri crate is not known to bootstrap.)
674
+ match builder.doc_tests {
675
+ DocTests::Yes => {}
676
+ DocTests::No => {
677
+ cargo.args(["--lib", "--bins", "--examples", "--tests", "--benches"]);
678
+ }
679
+ DocTests::Only => {
680
+ cargo.arg("--doc");
681
+ }
682
+ }
689
683
690
- // Tell `cargo miri` where to find things .
684
+ // Tell `cargo miri` where to find the sysroots .
691
685
cargo.env("MIRI_SYSROOT", &miri_sysroot);
692
686
cargo.env("MIRI_HOST_SYSROOT", sysroot);
693
- cargo.env("MIRI", &miri);
694
- // Debug things.
695
- cargo.env("RUST_BACKTRACE", "1");
696
687
688
+ // Finally, pass test-args and run everything.
689
+ cargo.arg("--").args(builder.config.test_args());
697
690
let mut cargo = Command::from(cargo);
698
691
{
692
+ let _guard = builder.msg_sysroot_tool(Kind::Test, stage, "cargo-miri", host, target);
699
693
let _time = helpers::timeit(builder);
700
694
builder.run(&mut cargo);
701
695
}
0 commit comments