From de41d01652d174b94929bd31d5a18745efecf6de Mon Sep 17 00:00:00 2001
From: Oli Scherer <github@oli-obk.de>
Date: Sun, 29 Sep 2024 08:46:50 +0200
Subject: [PATCH] Run all run(-dep) tests natively, too

---
 tests/pass-dep/libc/libc-mem.rs               |   1 +
 tests/pass-dep/num_cpus.rs                    |   1 +
 tests/pass-dep/page_size_override.rs          |   1 +
 tests/pass/adjacent-allocs.rs                 |   1 +
 tests/pass/atomic.rs                          |   1 +
 tests/pass/backtrace/backtrace-api-v0.rs      |   1 +
 tests/pass/backtrace/backtrace-api-v0.stdout  |  10 +-
 tests/pass/backtrace/backtrace-api-v1.rs      |   1 +
 tests/pass/backtrace/backtrace-api-v1.stdout  |  10 +-
 .../pass/backtrace/backtrace-global-alloc.rs  |   1 +
 tests/pass/backtrace/backtrace-std.rs         |   1 +
 tests/pass/cfg_miri.rs                        |   2 +
 .../pass/concurrency/thread_park_isolated.rs  |   1 +
 tests/pass/const-addrs.rs                     |   1 +
 tests/pass/dyn-traits.rs                      |   2 +
 tests/pass/extern_types.rs                    |   1 +
 tests/pass/float.rs                           |   2 +
 tests/pass/float_nan.rs                       |   2 +
 tests/pass/function_pointers.rs               |   2 +
 tests/pass/getpid.rs                          |   1 +
 tests/pass/hide_stdout.rs                     |   1 +
 tests/pass/intptrcast.rs                      |   1 +
 tests/pass/intrinsics/intrinsics.rs           |  25 +--
 tests/pass/miri_start.rs                      |   1 +
 tests/pass/no_std.rs                          |   1 +
 tests/pass/path.rs                            |   1 +
 tests/pass/protector-gc.rs                    |   1 +
 tests/pass/provenance.rs                      |   1 +
 tests/pass/ptr_int_casts.rs                   |   1 +
 tests/pass/ptr_int_from_exposed.rs            |   1 +
 .../available-parallelism-miri-num-cpus.rs    |   1 +
 tests/pass/shims/available-parallelism.rs     |   1 +
 tests/pass/shims/env/args.rs                  |   2 +
 .../shims/env/current_dir_with_isolation.rs   |   1 +
 tests/pass/shims/time-with-isolation.rs       |   1 +
 tests/pass/shims/time.rs                      |   1 +
 .../pass/shims/x86/intrinsics-x86-aes-vaes.rs |   1 +
 tests/pass/shims/x86/intrinsics-x86-avx.rs    |   1 +
 tests/pass/shims/x86/intrinsics-x86-avx2.rs   |   1 +
 tests/pass/shims/x86/intrinsics-x86-avx512.rs |   1 +
 tests/pass/shims/x86/intrinsics-x86-gfni.rs   |   1 +
 .../x86/intrinsics-x86-pause-without-sse2.rs  |   1 +
 tests/pass/stacked-borrows/issue-miri-2389.rs |   2 +
 tests/pass/stacked-borrows/stack-printing.rs  |   1 +
 tests/pass/tail_call.rs                       |   1 +
 tests/pass/tls/tls_macro_drop.rs              |   1 +
 tests/pass/tls/win_tls_callback.rs            |   2 +
 .../tree_borrows/cell-alternate-writes.rs     |   1 +
 tests/pass/tree_borrows/end-of-protector.rs   |   1 +
 tests/pass/tree_borrows/formatting.rs         |   1 +
 tests/pass/tree_borrows/reborrow-is-read.rs   |   1 +
 tests/pass/tree_borrows/reserved.rs           |   1 +
 tests/pass/tree_borrows/unique.rs             |   1 +
 tests/pass/tree_borrows/vec_unique.rs         |   1 +
 tests/pass/zero-sized-accesses-and-offsets.rs |   2 +
 tests/ui.rs                                   | 179 +++++++++++++++---
 56 files changed, 235 insertions(+), 50 deletions(-)

diff --git a/tests/pass-dep/libc/libc-mem.rs b/tests/pass-dep/libc/libc-mem.rs
index c399616b9a..de675322d3 100644
--- a/tests/pass-dep/libc/libc-mem.rs
+++ b/tests/pass-dep/libc/libc-mem.rs
@@ -1,3 +1,4 @@
+//@only-miri: testing specific alignment shenanigans
 #![feature(strict_provenance, pointer_is_aligned_to)]
 use std::{mem, ptr, slice};
 
diff --git a/tests/pass-dep/num_cpus.rs b/tests/pass-dep/num_cpus.rs
index 84339feb11..397f54953f 100644
--- a/tests/pass-dep/num_cpus.rs
+++ b/tests/pass-dep/num_cpus.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Zmiri-disable-isolation
+//@only-miri: fake cpu number
 
 fn main() {
     assert_eq!(num_cpus::get(), 1);
diff --git a/tests/pass-dep/page_size_override.rs b/tests/pass-dep/page_size_override.rs
index 68858f3875..74ea101b23 100644
--- a/tests/pass-dep/page_size_override.rs
+++ b/tests/pass-dep/page_size_override.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Zmiri-force-page-size=8
+//@only-miri: fake page size
 
 fn main() {
     let page_size = page_size::get();
diff --git a/tests/pass/adjacent-allocs.rs b/tests/pass/adjacent-allocs.rs
index 711c54fd68..63dac46157 100644
--- a/tests/pass/adjacent-allocs.rs
+++ b/tests/pass/adjacent-allocs.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Zmiri-permissive-provenance
+//@only-miri: CI found nonadjacent stack variables
 
 fn ensure_allocs_can_be_adjacent() {
     for _ in 0..512 {
diff --git a/tests/pass/atomic.rs b/tests/pass/atomic.rs
index f84fe825d0..4ba82d51bd 100644
--- a/tests/pass/atomic.rs
+++ b/tests/pass/atomic.rs
@@ -1,6 +1,7 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
 //@compile-flags: -Zmiri-strict-provenance
+//@only-miri: testing weak memory behaviour
 
 #![feature(strict_provenance, strict_provenance_atomic_ptr)]
 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
diff --git a/tests/pass/backtrace/backtrace-api-v0.rs b/tests/pass/backtrace/backtrace-api-v0.rs
index 3fff7921af..552d66e1be 100644
--- a/tests/pass/backtrace/backtrace-api-v0.rs
+++ b/tests/pass/backtrace/backtrace-api-v0.rs
@@ -1,4 +1,5 @@
 //@normalize-stderr-test: "::<.*>" -> ""
+//@only-miri: backtraces differ too much
 
 #[inline(never)]
 fn func_a() -> Box<[*mut ()]> {
diff --git a/tests/pass/backtrace/backtrace-api-v0.stdout b/tests/pass/backtrace/backtrace-api-v0.stdout
index 8c1bc5c353..3c625ae6c2 100644
--- a/tests/pass/backtrace/backtrace-api-v0.stdout
+++ b/tests/pass/backtrace/backtrace-api-v0.stdout
@@ -1,5 +1,5 @@
-tests/pass/backtrace/backtrace-api-v0.rs:24:14 (func_d)
-tests/pass/backtrace/backtrace-api-v0.rs:14:9 (func_c)
-tests/pass/backtrace/backtrace-api-v0.rs:9:5 (func_b::<u8>)
-tests/pass/backtrace/backtrace-api-v0.rs:5:5 (func_a)
-tests/pass/backtrace/backtrace-api-v0.rs:29:18 (main)
+tests/pass/backtrace/backtrace-api-v0.rs:25:14 (func_d)
+tests/pass/backtrace/backtrace-api-v0.rs:15:9 (func_c)
+tests/pass/backtrace/backtrace-api-v0.rs:10:5 (func_b::<u8>)
+tests/pass/backtrace/backtrace-api-v0.rs:6:5 (func_a)
+tests/pass/backtrace/backtrace-api-v0.rs:30:18 (main)
diff --git a/tests/pass/backtrace/backtrace-api-v1.rs b/tests/pass/backtrace/backtrace-api-v1.rs
index a3060abc39..b77b5c8498 100644
--- a/tests/pass/backtrace/backtrace-api-v1.rs
+++ b/tests/pass/backtrace/backtrace-api-v1.rs
@@ -1,4 +1,5 @@
 //@normalize-stderr-test: "::<.*>" -> ""
+//@only-miri: backtraces differ too much
 
 #[inline(never)]
 fn func_a() -> Box<[*mut ()]> {
diff --git a/tests/pass/backtrace/backtrace-api-v1.stdout b/tests/pass/backtrace/backtrace-api-v1.stdout
index 5c2995e132..17a77bc749 100644
--- a/tests/pass/backtrace/backtrace-api-v1.stdout
+++ b/tests/pass/backtrace/backtrace-api-v1.stdout
@@ -1,5 +1,5 @@
-tests/pass/backtrace/backtrace-api-v1.rs:27:9 (func_d)
-tests/pass/backtrace/backtrace-api-v1.rs:14:9 (func_c)
-tests/pass/backtrace/backtrace-api-v1.rs:9:5 (func_b::<u8>)
-tests/pass/backtrace/backtrace-api-v1.rs:5:5 (func_a)
-tests/pass/backtrace/backtrace-api-v1.rs:34:18 (main)
+tests/pass/backtrace/backtrace-api-v1.rs:28:9 (func_d)
+tests/pass/backtrace/backtrace-api-v1.rs:15:9 (func_c)
+tests/pass/backtrace/backtrace-api-v1.rs:10:5 (func_b::<u8>)
+tests/pass/backtrace/backtrace-api-v1.rs:6:5 (func_a)
+tests/pass/backtrace/backtrace-api-v1.rs:35:18 (main)
diff --git a/tests/pass/backtrace/backtrace-global-alloc.rs b/tests/pass/backtrace/backtrace-global-alloc.rs
index 6660e5bb57..ddc9ed2c70 100644
--- a/tests/pass/backtrace/backtrace-global-alloc.rs
+++ b/tests/pass/backtrace/backtrace-global-alloc.rs
@@ -1,5 +1,6 @@
 //@compile-flags: -Zmiri-disable-isolation
 //@rustc-env: RUST_BACKTRACE=1
+//@only-miri: backtraces differ too much
 
 use std::alloc::System;
 use std::backtrace::Backtrace;
diff --git a/tests/pass/backtrace/backtrace-std.rs b/tests/pass/backtrace/backtrace-std.rs
index b2a5ac1802..f4f4579a42 100644
--- a/tests/pass/backtrace/backtrace-std.rs
+++ b/tests/pass/backtrace/backtrace-std.rs
@@ -1,5 +1,6 @@
 //@compile-flags: -Zmiri-disable-isolation
 //@rustc-env: RUST_BACKTRACE=1
+//@only-miri: backtraces differ too much
 
 use std::backtrace::Backtrace;
 
diff --git a/tests/pass/cfg_miri.rs b/tests/pass/cfg_miri.rs
index 558b9a4f50..7cf1184bd8 100644
--- a/tests/pass/cfg_miri.rs
+++ b/tests/pass/cfg_miri.rs
@@ -1,3 +1,5 @@
+//@only-miri: cfg miri test
+
 fn main() {
     assert!(cfg!(miri));
 }
diff --git a/tests/pass/concurrency/thread_park_isolated.rs b/tests/pass/concurrency/thread_park_isolated.rs
index 35145fe9bd..0c9fa6ae70 100644
--- a/tests/pass/concurrency/thread_park_isolated.rs
+++ b/tests/pass/concurrency/thread_park_isolated.rs
@@ -1,4 +1,5 @@
 //@ignore-target: apple # park_timeout on macOS uses the system clock
+//@only-miri: runtime has nondeterministic execution and may be slower than 210ms
 use std::thread;
 use std::time::{Duration, Instant};
 
diff --git a/tests/pass/const-addrs.rs b/tests/pass/const-addrs.rs
index 727c67ebfb..95eff2b042 100644
--- a/tests/pass/const-addrs.rs
+++ b/tests/pass/const-addrs.rs
@@ -8,6 +8,7 @@
 // stack frame, breaking this test.
 //@compile-flags: -Zinline-mir=no
 #![feature(strict_provenance)]
+//@only-miri: expecting that pointer addresses have specific behaviour
 
 const EVALS: usize = 256;
 
diff --git a/tests/pass/dyn-traits.rs b/tests/pass/dyn-traits.rs
index f622012096..35c63bcadf 100644
--- a/tests/pass/dyn-traits.rs
+++ b/tests/pass/dyn-traits.rs
@@ -1,3 +1,5 @@
+//@only-miri: expecting that vtables are not deduplicated
+
 fn ref_box_dyn() {
     struct Struct(i32);
 
diff --git a/tests/pass/extern_types.rs b/tests/pass/extern_types.rs
index eade5c6ac0..b04c62ae9d 100644
--- a/tests/pass/extern_types.rs
+++ b/tests/pass/extern_types.rs
@@ -1,5 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
+//@[stack]only-miri: miri specific warning
 #![feature(extern_types, strict_provenance)]
 
 use std::ptr;
diff --git a/tests/pass/float.rs b/tests/pass/float.rs
index 6ab18a5345..11083432e1 100644
--- a/tests/pass/float.rs
+++ b/tests/pass/float.rs
@@ -6,6 +6,8 @@
 #![allow(arithmetic_overflow)]
 #![allow(internal_features)]
 
+//@only-miri: FIXME: linker errors due to some missing libc float functions
+
 use std::any::type_name;
 use std::cmp::min;
 use std::fmt::{Debug, Display, LowerHex};
diff --git a/tests/pass/float_nan.rs b/tests/pass/float_nan.rs
index cadbbd58af..29995b44c7 100644
--- a/tests/pass/float_nan.rs
+++ b/tests/pass/float_nan.rs
@@ -1,3 +1,5 @@
+//@only-miri: FIXME: did not get value that should be possible: 0x7fc00000 (NaN: Pos, Quiet, payload = 0x0)
+
 #![feature(float_gamma, portable_simd, core_intrinsics)]
 use std::collections::HashSet;
 use std::fmt;
diff --git a/tests/pass/function_pointers.rs b/tests/pass/function_pointers.rs
index a5c4bc5e0d..b8e5248faa 100644
--- a/tests/pass/function_pointers.rs
+++ b/tests/pass/function_pointers.rs
@@ -1,3 +1,5 @@
+//@only-miri: testing that function pointers are inequal
+
 use std::mem;
 
 trait Answer {
diff --git a/tests/pass/getpid.rs b/tests/pass/getpid.rs
index f350fafff4..0a5383bff0 100644
--- a/tests/pass/getpid.rs
+++ b/tests/pass/getpid.rs
@@ -1,5 +1,6 @@
 //@revisions: with_isolation without_isolation
 //@[without_isolation] compile-flags: -Zmiri-disable-isolation
+//@only-miri: miri isolation mode test
 
 fn getpid() -> u32 {
     std::process::id()
diff --git a/tests/pass/hide_stdout.rs b/tests/pass/hide_stdout.rs
index cfd05a8396..f2976c5c44 100644
--- a/tests/pass/hide_stdout.rs
+++ b/tests/pass/hide_stdout.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Zmiri-mute-stdout-stderr
+//@only-miri: miri flag test
 
 fn main() {
     println!("print to stdout");
diff --git a/tests/pass/intptrcast.rs b/tests/pass/intptrcast.rs
index a304f2751b..98baa46b73 100644
--- a/tests/pass/intptrcast.rs
+++ b/tests/pass/intptrcast.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Zmiri-permissive-provenance
+//@only-miri: FIXME: CI found a miscompile: `assert_eq!(2, 2)` failed in `should_be_ub`
 
 use std::mem;
 
diff --git a/tests/pass/intrinsics/intrinsics.rs b/tests/pass/intrinsics/intrinsics.rs
index 89289a25d5..04399afbf8 100644
--- a/tests/pass/intrinsics/intrinsics.rs
+++ b/tests/pass/intrinsics/intrinsics.rs
@@ -33,20 +33,23 @@ fn main() {
     assert_eq!(intrinsics::likely(false), false);
     assert_eq!(intrinsics::unlikely(true), true);
 
-    let mut saw_true = false;
-    let mut saw_false = false;
+    #[cfg(miri)]
+    {
+        let mut saw_true = false;
+        let mut saw_false = false;
 
-    for _ in 0..50 {
-        if intrinsics::is_val_statically_known(0) {
-            saw_true = true;
-        } else {
-            saw_false = true;
+        for _ in 0..50 {
+            if intrinsics::is_val_statically_known(0) {
+                saw_true = true;
+            } else {
+                saw_false = true;
+            }
         }
+        assert!(
+            saw_true && saw_false,
+            "`is_val_statically_known` failed to return both true and false. Congrats, you won the lottery!"
+        );
     }
-    assert!(
-        saw_true && saw_false,
-        "`is_val_statically_known` failed to return both true and false. Congrats, you won the lottery!"
-    );
 
     intrinsics::forget(Bomb);
 
diff --git a/tests/pass/miri_start.rs b/tests/pass/miri_start.rs
index 756a1f60be..f1f4906902 100644
--- a/tests/pass/miri_start.rs
+++ b/tests/pass/miri_start.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Cpanic=abort
+//@only-miri: using miri internal apis
 #![no_main]
 #![no_std]
 
diff --git a/tests/pass/no_std.rs b/tests/pass/no_std.rs
index fc1c16f5fb..3774c6f13f 100644
--- a/tests/pass/no_std.rs
+++ b/tests/pass/no_std.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Cpanic=abort
+//@only-miri: using miri internal apis
 #![feature(start)]
 #![no_std]
 
diff --git a/tests/pass/path.rs b/tests/pass/path.rs
index 299ee6cfe9..bb86791d07 100644
--- a/tests/pass/path.rs
+++ b/tests/pass/path.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Zmiri-disable-isolation
+//@only-miri: using miri internal apis
 use std::path::{Path, PathBuf, absolute};
 
 #[path = "../utils/mod.rs"]
diff --git a/tests/pass/protector-gc.rs b/tests/pass/protector-gc.rs
index 4e422c323e..f6958d5311 100644
--- a/tests/pass/protector-gc.rs
+++ b/tests/pass/protector-gc.rs
@@ -2,6 +2,7 @@
 // allocation is still live. If the provenance GC only knows about the BorTag that is protected,
 // we can ICE. This test checks that we don't.
 // See https://github.com/rust-lang/miri/issues/3228
+//@only-miri: using miri internal apis
 
 #[path = "../utils/mod.rs"]
 mod utils;
diff --git a/tests/pass/provenance.rs b/tests/pass/provenance.rs
index 2e4d240cc4..ed523b18ee 100644
--- a/tests/pass/provenance.rs
+++ b/tests/pass/provenance.rs
@@ -1,5 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
+//@only-miri: FIXME compiler panic: assertion failed: matches!(scalar, Scalar::Int(..))
 #![feature(strict_provenance)]
 use std::{mem, ptr};
 
diff --git a/tests/pass/ptr_int_casts.rs b/tests/pass/ptr_int_casts.rs
index 4e274f6298..dba3e89f91 100644
--- a/tests/pass/ptr_int_casts.rs
+++ b/tests/pass/ptr_int_casts.rs
@@ -2,6 +2,7 @@
 // Tree Borrows doesn't support int2ptr casts, but let's make sure we don't immediately crash either.
 //@[tree]compile-flags: -Zmiri-tree-borrows
 //@[stack]compile-flags: -Zmiri-permissive-provenance
+//@[tree]only-miri: miri specific warnings
 use std::{mem, ptr};
 
 fn eq_ref<T>(x: &T, y: &T) -> bool {
diff --git a/tests/pass/ptr_int_from_exposed.rs b/tests/pass/ptr_int_from_exposed.rs
index ade5f53778..7cd5fa9ca0 100644
--- a/tests/pass/ptr_int_from_exposed.rs
+++ b/tests/pass/ptr_int_from_exposed.rs
@@ -2,6 +2,7 @@
 // Tree Borrows doesn't support int2ptr casts, but let's make sure we don't immediately crash either.
 //@[tree]compile-flags: -Zmiri-tree-borrows
 //@[stack]compile-flags: -Zmiri-permissive-provenance
+//@[tree]only-miri: miri specific warnings
 #![feature(strict_provenance, exposed_provenance)]
 
 use std::ptr;
diff --git a/tests/pass/shims/available-parallelism-miri-num-cpus.rs b/tests/pass/shims/available-parallelism-miri-num-cpus.rs
index 0d96bc2f5e..626e702095 100644
--- a/tests/pass/shims/available-parallelism-miri-num-cpus.rs
+++ b/tests/pass/shims/available-parallelism-miri-num-cpus.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Zmiri-num-cpus=1024
+//@only-miri: download more cores
 
 use std::num::NonZero;
 use std::thread::available_parallelism;
diff --git a/tests/pass/shims/available-parallelism.rs b/tests/pass/shims/available-parallelism.rs
index 77fb78424b..dfab263ada 100644
--- a/tests/pass/shims/available-parallelism.rs
+++ b/tests/pass/shims/available-parallelism.rs
@@ -1,5 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
+//@only-miri: real system can have different number of cores
 fn main() {
     assert_eq!(std::thread::available_parallelism().unwrap().get(), 1);
 }
diff --git a/tests/pass/shims/env/args.rs b/tests/pass/shims/env/args.rs
index 0116dce499..a6ba0e4a90 100644
--- a/tests/pass/shims/env/args.rs
+++ b/tests/pass/shims/env/args.rs
@@ -1,3 +1,5 @@
+//@only-miri: the actual command changes between platforms with rustc
+
 fn main() {
     for arg in std::env::args() {
         println!("{}", arg);
diff --git a/tests/pass/shims/env/current_dir_with_isolation.rs b/tests/pass/shims/env/current_dir_with_isolation.rs
index 9dbcfeae2d..eab69542e3 100644
--- a/tests/pass/shims/env/current_dir_with_isolation.rs
+++ b/tests/pass/shims/env/current_dir_with_isolation.rs
@@ -1,6 +1,7 @@
 //@compile-flags: -Zmiri-isolation-error=warn-nobacktrace
 //@normalize-stderr-test: "(getcwd|GetCurrentDirectoryW)" -> "$$GETCWD"
 //@normalize-stderr-test: "(chdir|SetCurrentDirectoryW)" -> "$$SETCWD"
+//@only-miri: testing miri specific warnings
 
 use std::env;
 use std::io::ErrorKind;
diff --git a/tests/pass/shims/time-with-isolation.rs b/tests/pass/shims/time-with-isolation.rs
index e7b1624412..0ddd39178a 100644
--- a/tests/pass/shims/time-with-isolation.rs
+++ b/tests/pass/shims/time-with-isolation.rs
@@ -1,4 +1,5 @@
 use std::time::{Duration, Instant};
+//@only-miri: sleeps for one hour
 
 fn test_sleep() {
     // We sleep a *long* time here -- but the clock is virtual so the test should still pass quickly.
diff --git a/tests/pass/shims/time.rs b/tests/pass/shims/time.rs
index 226f04ade0..1d4d36692c 100644
--- a/tests/pass/shims/time.rs
+++ b/tests/pass/shims/time.rs
@@ -1,4 +1,5 @@
 //@compile-flags: -Zmiri-disable-isolation
+//@only-miri: runs under 1ms on a real system
 
 use std::time::{Duration, Instant, SystemTime};
 
diff --git a/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs b/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs
index 47f086f734..77daf67b1c 100644
--- a/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs
+++ b/tests/pass/shims/x86/intrinsics-x86-aes-vaes.rs
@@ -1,6 +1,7 @@
 // We're testing x86 target specific features
 //@only-target: x86_64 i686
 //@compile-flags: -C target-feature=+aes,+vaes,+avx512f
+//@only-miri: FIXME: stability warnings only with rustc and some assert failures
 
 #![feature(avx512_target_feature, stdarch_x86_avx512)]
 
diff --git a/tests/pass/shims/x86/intrinsics-x86-avx.rs b/tests/pass/shims/x86/intrinsics-x86-avx.rs
index b3c2434c0d..0d8e104d75 100644
--- a/tests/pass/shims/x86/intrinsics-x86-avx.rs
+++ b/tests/pass/shims/x86/intrinsics-x86-avx.rs
@@ -1,6 +1,7 @@
 // We're testing x86 target specific features
 //@only-target: x86_64 i686
 //@compile-flags: -C target-feature=+avx
+//@only-miri: FIXME: some assert failures with rustc
 
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
diff --git a/tests/pass/shims/x86/intrinsics-x86-avx2.rs b/tests/pass/shims/x86/intrinsics-x86-avx2.rs
index de1abc8184..e64fdb5dd5 100644
--- a/tests/pass/shims/x86/intrinsics-x86-avx2.rs
+++ b/tests/pass/shims/x86/intrinsics-x86-avx2.rs
@@ -1,6 +1,7 @@
 // We're testing x86 target specific features
 //@only-target: x86_64 i686
 //@compile-flags: -C target-feature=+avx2
+//@only-miri: FIXME: some assert failures with rustc
 
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
diff --git a/tests/pass/shims/x86/intrinsics-x86-avx512.rs b/tests/pass/shims/x86/intrinsics-x86-avx512.rs
index db59306389..9293333fc4 100644
--- a/tests/pass/shims/x86/intrinsics-x86-avx512.rs
+++ b/tests/pass/shims/x86/intrinsics-x86-avx512.rs
@@ -1,6 +1,7 @@
 // We're testing x86 target specific features
 //@only-target: x86_64 i686
 //@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bitalg,+avx512vpopcntdq
+//@only-miri: FIXME: stability warnings only with rustc and some assert failures
 
 #![feature(avx512_target_feature)]
 #![feature(stdarch_x86_avx512)]
diff --git a/tests/pass/shims/x86/intrinsics-x86-gfni.rs b/tests/pass/shims/x86/intrinsics-x86-gfni.rs
index a629e2acfe..6d365b26ad 100644
--- a/tests/pass/shims/x86/intrinsics-x86-gfni.rs
+++ b/tests/pass/shims/x86/intrinsics-x86-gfni.rs
@@ -1,6 +1,7 @@
 // We're testing x86 target specific features
 //@only-target: x86_64 i686
 //@compile-flags: -C target-feature=+gfni,+avx512f
+//@only-miri: FIXME: returns weird exit code
 
 // The constants in the tests below are just bit patterns. They should not
 // be interpreted as integers; signedness does not make sense for them, but
diff --git a/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.rs b/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.rs
index 4d5ddd75f3..d6ca057738 100644
--- a/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.rs
+++ b/tests/pass/shims/x86/intrinsics-x86-pause-without-sse2.rs
@@ -1,6 +1,7 @@
 // We're testing x86 target specific features
 //@only-target: x86_64 i686
 //@compile-flags: -C target-feature=-sse2
+//@only-miri: FIXME: some assert failures with rustc
 
 #[cfg(target_arch = "x86")]
 use std::arch::x86::*;
diff --git a/tests/pass/stacked-borrows/issue-miri-2389.rs b/tests/pass/stacked-borrows/issue-miri-2389.rs
index 469122095e..ddb3e3efe4 100644
--- a/tests/pass/stacked-borrows/issue-miri-2389.rs
+++ b/tests/pass/stacked-borrows/issue-miri-2389.rs
@@ -1,3 +1,5 @@
+//@only-miri: emits miri-specific warnings
+
 use std::cell::Cell;
 
 fn main() {
diff --git a/tests/pass/stacked-borrows/stack-printing.rs b/tests/pass/stacked-borrows/stack-printing.rs
index 1478b21d6c..02ca0d63dd 100644
--- a/tests/pass/stacked-borrows/stack-printing.rs
+++ b/tests/pass/stacked-borrows/stack-printing.rs
@@ -1,6 +1,7 @@
 // We disable the GC for this test because it would change what is printed. We are testing the
 // printing, not how it interacts with the GC.
 //@compile-flags: -Zmiri-permissive-provenance -Zmiri-provenance-gc=0
+//@only-miri: using miri internal apis
 
 #![feature(strict_provenance)]
 use std::alloc::{self, Layout};
diff --git a/tests/pass/tail_call.rs b/tests/pass/tail_call.rs
index f620070639..3962638235 100644
--- a/tests/pass/tail_call.rs
+++ b/tests/pass/tail_call.rs
@@ -1,5 +1,6 @@
 #![allow(incomplete_features)]
 #![feature(explicit_tail_calls)]
+//@only-miri: FIXME: tail calls not supported by llvm backend yet
 
 fn main() {
     assert_eq!(factorial(10), 3_628_800);
diff --git a/tests/pass/tls/tls_macro_drop.rs b/tests/pass/tls/tls_macro_drop.rs
index 0d8a1cef51..9be41393fc 100644
--- a/tests/pass/tls/tls_macro_drop.rs
+++ b/tests/pass/tls/tls_macro_drop.rs
@@ -1,5 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
+//@only-miri: FIXME: gets stuck somewhere on windows at least
 
 use std::cell::RefCell;
 use std::thread;
diff --git a/tests/pass/tls/win_tls_callback.rs b/tests/pass/tls/win_tls_callback.rs
index a915568292..f8204d372a 100644
--- a/tests/pass/tls/win_tls_callback.rs
+++ b/tests/pass/tls/win_tls_callback.rs
@@ -5,6 +5,8 @@
 // that's not what this test is about.
 //@compile-flags: -Zmiri-ignore-leaks
 
+//@only-miri: FIXME: fatal runtime error: thread::set_current should only be called once per thread
+
 #[link_section = ".CRT$XLB"]
 #[used] // Miri only considers explicitly `#[used]` statics for `lookup_link_section`
 pub static CALLBACK: unsafe extern "system" fn(*const (), u32, *const ()) = tls_callback;
diff --git a/tests/pass/tree_borrows/cell-alternate-writes.rs b/tests/pass/tree_borrows/cell-alternate-writes.rs
index 3269acb511..9f1e3d8686 100644
--- a/tests/pass/tree_borrows/cell-alternate-writes.rs
+++ b/tests/pass/tree_borrows/cell-alternate-writes.rs
@@ -1,5 +1,6 @@
 // We disable the GC for this test because it would change what is printed.
 //@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
+//@only-miri: uses miri internal APIs
 #[path = "../../utils/mod.rs"]
 #[macro_use]
 mod utils;
diff --git a/tests/pass/tree_borrows/end-of-protector.rs b/tests/pass/tree_borrows/end-of-protector.rs
index 261419b225..a7c6bb4f77 100644
--- a/tests/pass/tree_borrows/end-of-protector.rs
+++ b/tests/pass/tree_borrows/end-of-protector.rs
@@ -1,5 +1,6 @@
 // We disable the GC for this test because it would change what is printed.
 //@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
+//@only-miri: uses miri internals
 
 // Check that a protector goes back to normal behavior when the function
 // returns.
diff --git a/tests/pass/tree_borrows/formatting.rs b/tests/pass/tree_borrows/formatting.rs
index 8898205bfb..5d67dd28a6 100644
--- a/tests/pass/tree_borrows/formatting.rs
+++ b/tests/pass/tree_borrows/formatting.rs
@@ -1,5 +1,6 @@
 // We disable the GC for this test because it would change what is printed.
 //@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
+//@only-miri: uses miri internals
 
 #[path = "../../utils/mod.rs"]
 #[macro_use]
diff --git a/tests/pass/tree_borrows/reborrow-is-read.rs b/tests/pass/tree_borrows/reborrow-is-read.rs
index 4fbccef236..e00d12fe85 100644
--- a/tests/pass/tree_borrows/reborrow-is-read.rs
+++ b/tests/pass/tree_borrows/reborrow-is-read.rs
@@ -1,5 +1,6 @@
 // We disable the GC for this test because it would change what is printed.
 //@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
+//@only-miri: uses miri internal APIs
 
 #[path = "../../utils/mod.rs"]
 #[macro_use]
diff --git a/tests/pass/tree_borrows/reserved.rs b/tests/pass/tree_borrows/reserved.rs
index f93cac8361..60db1bc3bc 100644
--- a/tests/pass/tree_borrows/reserved.rs
+++ b/tests/pass/tree_borrows/reserved.rs
@@ -1,5 +1,6 @@
 // We disable the GC for this test because it would change what is printed.
 //@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
+//@only-miri: uses miri internals
 
 #[path = "../../utils/mod.rs"]
 #[macro_use]
diff --git a/tests/pass/tree_borrows/unique.rs b/tests/pass/tree_borrows/unique.rs
index f1ca1b51aa..a1a740c3e9 100644
--- a/tests/pass/tree_borrows/unique.rs
+++ b/tests/pass/tree_borrows/unique.rs
@@ -2,6 +2,7 @@
 // We disable the GC for this test because it would change what is printed.
 //@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
 //@[uniq]compile-flags: -Zmiri-unique-is-unique
+//@only-miri: uses miri internals
 
 #![feature(ptr_internals)]
 
diff --git a/tests/pass/tree_borrows/vec_unique.rs b/tests/pass/tree_borrows/vec_unique.rs
index af4c3b0693..f40977c81f 100644
--- a/tests/pass/tree_borrows/vec_unique.rs
+++ b/tests/pass/tree_borrows/vec_unique.rs
@@ -2,6 +2,7 @@
 // We disable the GC for this test because it would change what is printed.
 //@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0
 //@[uniq]compile-flags: -Zmiri-unique-is-unique
+//@only-miri: uses miri internal apis
 
 #![feature(vec_into_raw_parts)]
 
diff --git a/tests/pass/zero-sized-accesses-and-offsets.rs b/tests/pass/zero-sized-accesses-and-offsets.rs
index a3356b682a..17af1f4008 100644
--- a/tests/pass/zero-sized-accesses-and-offsets.rs
+++ b/tests/pass/zero-sized-accesses-and-offsets.rs
@@ -1,6 +1,8 @@
 //! Tests specific for <https://github.com/rust-lang/rust/issues/117945>: zero-sized operations.
 #![feature(strict_provenance)]
 
+//@only-miri: FIXME: copy_nonoverlapping assertion triggered
+
 use std::ptr;
 
 fn main() {
diff --git a/tests/ui.rs b/tests/ui.rs
index 2912aa85ee..3accccc078 100644
--- a/tests/ui.rs
+++ b/tests/ui.rs
@@ -9,15 +9,22 @@ use colored::*;
 use regex::bytes::Regex;
 use ui_test::build_manager::BuildManager;
 use ui_test::color_eyre::eyre::{Context, Result};
+use ui_test::custom_flags::Flag;
 use ui_test::custom_flags::edition::Edition;
+use ui_test::custom_flags::run::Run;
 use ui_test::dependencies::DependencyBuilder;
-use ui_test::per_test_config::TestConfig;
+use ui_test::per_test_config::{Comments, Condition, TestConfig};
 use ui_test::spanned::Spanned;
-use ui_test::{CommandBuilder, Config, Format, Match, ignore_output_conflict, status_emitter};
+use ui_test::{
+    CommandBuilder, Config, Errored, Format, Match, ignore_output_conflict, status_emitter,
+};
 
 #[derive(Copy, Clone, Debug)]
 enum Mode {
-    Pass,
+    Pass {
+        /// Whether to compile and run with rustc instead of miri
+        rustc: bool,
+    },
     /// Requires annotations
     Fail,
     /// Not used for tests, but for `miri run --dep`
@@ -107,8 +114,89 @@ fn miri_config(
         ..Config::rustc(path)
     };
 
+    if let Mode::Pass { rustc: true } = mode {
+        config.comment_defaults.base().add_custom("run", Run {
+            exit_code: 0,
+            output_conflict_handling: Some(|path, actual, errors, config| {
+                let path = path.with_file_name(
+                    path.file_name().unwrap().to_str().unwrap().replace(".run.", "."),
+                );
+                // Blessing is only allowed in miri mode, rustc mode must match
+                ui_test::error_on_output_conflict(&path, actual, errors, config);
+            }),
+        });
+        config.program.envs.push(("MIRI_BE_RUSTC".into(), Some("host".into())));
+
+        #[derive(Debug)]
+        struct Strip;
+
+        impl Flag for Strip {
+            fn clone_inner(&self) -> Box<dyn Flag> {
+                Box::new(Strip)
+            }
+
+            fn must_be_unique(&self) -> bool {
+                true
+            }
+
+            fn apply(
+                &self,
+                cmd: &mut Command,
+                _config: &TestConfig,
+                _build_manager: &BuildManager,
+            ) -> Result<(), Errored> {
+                let mut c = Command::new(cmd.get_program());
+                for (k, v) in cmd.get_envs() {
+                    match v {
+                        Some(v) => c.env(k, v),
+                        None => c.env_remove(k),
+                    };
+                }
+                if let Some(dir) = cmd.get_current_dir() {
+                    c.current_dir(dir);
+                }
+                c.args(
+                    cmd.get_args().filter(|arg| !arg.as_encoded_bytes().starts_with(b"-Zmiri-")),
+                );
+                *cmd = c;
+                Ok(())
+            }
+
+            fn test_condition(
+                &self,
+                _config: &Config,
+                comments: &Comments,
+                revision: &str,
+            ) -> bool {
+                for rev in comments.for_revision(revision) {
+                    for arg in &rev.compile_flags {
+                        // A real execution will preempt, and thus behave differently
+                        if arg.starts_with("-Zmiri-preemption-rate") {
+                            return true;
+                        }
+                        // FIXME: can probably support these somehow
+                        if arg.starts_with("-Zmiri-env") {
+                            return true;
+                        }
+                    }
+                }
+                false
+            }
+        }
+
+        config.comment_defaults.base().add_custom("strip_dash_z_miri", Strip);
+
+        // Only run on no target if `only-miri` is passed.
+        config
+            .custom_comments
+            .insert("only-miri", |parser, _, _| parser.only.push(Condition::Target(vec![])));
+    } else {
+        // Nop, we are in miri mode
+        config.custom_comments.insert("only-miri", |_, _, _| {});
+    }
+
     config.comment_defaults.base().exit_status = match mode {
-        Mode::Pass => Some(0),
+        Mode::Pass { .. } => Some(0),
         Mode::Fail => Some(1),
         Mode::RunDep => None,
         Mode::Panic => Some(101),
@@ -128,18 +216,23 @@ fn miri_config(
     config.comment_defaults.base().add_custom("edition", Edition("2021".into()));
 
     if let Some(WithDependencies { bless }) = with_dependencies {
+        let program = match mode {
+            Mode::Pass { rustc: true } => CommandBuilder::cargo(),
+            _ =>
+                CommandBuilder {
+                    // Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary.
+                    // (It's a separate crate, so we don't get an env var from cargo.)
+                    program: miri_path()
+                        .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
+                    // There is no `cargo miri build` so we just use `cargo miri run`.
+                    args: ["miri", "run"].into_iter().map(Into::into).collect(),
+                    // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
+                    envs: vec![("RUSTFLAGS".into(), None)],
+                    ..CommandBuilder::cargo()
+                },
+        };
         config.comment_defaults.base().set_custom("dependencies", DependencyBuilder {
-            program: CommandBuilder {
-                // Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary.
-                // (It's a separate crate, so we don't get an env var from cargo.)
-                program: miri_path()
-                    .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
-                // There is no `cargo miri build` so we just use `cargo miri run`.
-                args: ["miri", "run"].into_iter().map(Into::into).collect(),
-                // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
-                envs: vec![("RUSTFLAGS".into(), None)],
-                ..CommandBuilder::cargo()
-            },
+            program,
             crate_manifest_path: Path::new("test_dependencies").join("Cargo.toml"),
             build_std: None,
             bless_lockfile: bless,
@@ -163,7 +256,19 @@ fn run_tests(
 
     let mut config = miri_config(target, path, mode, with_dependencies);
     config.with_args(&args);
-    config.bless_command = Some("./miri test --bless".into());
+    if let Mode::Pass { rustc: true } = mode {
+        config.fill_host_and_target()?;
+        // Rustc mode only works on the host
+        if !config.host_matches_target() {
+            return Ok(());
+        }
+        config.output_conflict_handling = ui_test::ignore_output_conflict;
+
+        config.bless_command =
+            Some("add `//@only-miri:` to the test if it cannot be run on the host directly".into());
+    } else {
+        config.bless_command = Some("./miri test --bless".into());
+    }
 
     if env::var_os("MIRI_SKIP_UI_CHECKS").is_some() {
         assert!(!args.bless, "cannot use RUSTC_BLESS and MIRI_SKIP_UI_CHECKS at the same time");
@@ -174,17 +279,25 @@ fn run_tests(
     config.program.envs.push(("MIRI_ENV_VAR_TEST".into(), Some("0".into())));
     // Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
     config.program.envs.push(("MIRI_TEMP".into(), Some(tmpdir.to_owned().into())));
-    // If a test ICEs, we want to see a backtrace.
-    config.program.envs.push(("RUST_BACKTRACE".into(), Some("1".into())));
 
     // Add some flags we always want.
-    config.program.args.push(
-        format!(
-            "--sysroot={}",
-            env::var("MIRI_SYSROOT").expect("MIRI_SYSROOT must be set to run the ui test suite")
-        )
-        .into(),
-    );
+    match mode {
+        // rustc mode doesn't want miri specific flags
+        Mode::Pass { rustc: true } => {}
+        _ => {
+            // If a test ICEs, we want to see a backtrace.
+            config.program.envs.push(("RUST_BACKTRACE".into(), Some("1".into())));
+            config.program.args.push(
+                format!(
+                    "--sysroot={}",
+                    env::var("MIRI_SYSROOT")
+                        .expect("MIRI_SYSROOT must be set to run the ui test suite")
+                )
+                .into(),
+            );
+        }
+    }
+
     config.program.args.push("-Dwarnings".into());
     config.program.args.push("-Dunused".into());
     config.program.args.push("-Ainternal_features".into());
@@ -274,7 +387,7 @@ regexes! {
     // Windows file paths
     r"\\"                           => "/",
     // erase Rust stdlib path
-    "[^ \n`]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/",
+    "[^ \n`]*/(rust[^/]*|checkout|rustc/[0-9a-f]+)/library/" => "RUSTLIB/",
     // erase platform file paths
     "sys/pal/[a-z]+/"                    => "sys/pal/PLATFORM/",
     // erase paths into the crate registry
@@ -327,13 +440,21 @@ fn main() -> Result<()> {
         }
     }
 
-    ui(Mode::Pass, "tests/pass", &target, WithoutDependencies, tmpdir.path())?;
-    ui(Mode::Pass, "tests/pass-dep", &target, WithDependencies, tmpdir.path())?;
+    for rustc in [false, true] {
+        ui(Mode::Pass { rustc }, "tests/pass", &target, WithoutDependencies, tmpdir.path())?;
+        ui(Mode::Pass { rustc }, "tests/pass-dep", &target, WithDependencies, tmpdir.path())?;
+    }
     ui(Mode::Panic, "tests/panic", &target, WithDependencies, tmpdir.path())?;
     ui(Mode::Fail, "tests/fail", &target, WithoutDependencies, tmpdir.path())?;
     ui(Mode::Fail, "tests/fail-dep", &target, WithDependencies, tmpdir.path())?;
     if cfg!(unix) {
-        ui(Mode::Pass, "tests/native-lib/pass", &target, WithoutDependencies, tmpdir.path())?;
+        ui(
+            Mode::Pass { rustc: false },
+            "tests/native-lib/pass",
+            &target,
+            WithoutDependencies,
+            tmpdir.path(),
+        )?;
         ui(Mode::Fail, "tests/native-lib/fail", &target, WithoutDependencies, tmpdir.path())?;
     }