From 3c01d1e3c063021444ac66940d46cde10fd22960 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Wed, 15 Oct 2025 02:27:37 +0000 Subject: [PATCH 1/3] Use delay_span_bug in validate-mir. --- compiler/rustc_mir_transform/src/validate.rs | 27 ++++++++++--------- tests/crashes/140850.rs | 2 +- .../coroutine/non-send-dyn-send-ice.rs} | 6 +++-- .../ui/coroutine/non-send-dyn-send-ice.stderr | 23 ++++++++++++++++ .../branch-closure-parameter.rs} | 5 ++-- .../branch-closure-parameter.stderr | 15 +++++++++++ 6 files changed, 61 insertions(+), 17 deletions(-) rename tests/{crashes/137916.rs => ui/coroutine/non-send-dyn-send-ice.rs} (54%) create mode 100644 tests/ui/coroutine/non-send-dyn-send-ice.stderr rename tests/{crashes/126680.rs => ui/type-alias-impl-trait/branch-closure-parameter.rs} (80%) create mode 100644 tests/ui/type-alias-impl-trait/branch-closure-parameter.stderr diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 1f0490a120152..4f9cd6d1820a6 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -11,12 +11,12 @@ use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Upcast, Variance, }; -use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::debuginfo::debuginfo_locals; use rustc_trait_selection::traits::ObligationCtxt; @@ -122,18 +122,17 @@ struct CfgChecker<'a, 'tcx> { impl<'a, 'tcx> CfgChecker<'a, 'tcx> { #[track_caller] - fn fail(&self, location: Location, msg: impl AsRef) { + fn fail(&self, location: Location, msg: impl std::fmt::Display) { // We might see broken MIR when other errors have already occurred. - if self.tcx.dcx().has_errors().is_none() { - span_bug!( - self.body.source_info(location).span, + // But we may have some cases of errors happening *after* MIR construction, + // for instance because of generic constants or coroutines. + self.tcx.dcx().span_delayed_bug( + self.body.source_info(location).span, + format!( "broken MIR in {:?} ({}) at {:?}:\n{}", - self.body.source.instance, - self.when, - location, - msg.as_ref(), - ); - } + self.body.source.instance, self.when, location, msg, + ), + ); } fn check_edge(&mut self, location: Location, bb: BasicBlock, edge_kind: EdgeKind) { @@ -1641,7 +1640,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::Int(int) => int.normalize(target_width).bit_width().unwrap(), ty::Char => 32, ty::Bool => 1, - other => bug!("unhandled type: {:?}", other), + other => { + self.fail(location, format!("unhandled type in SwitchInt {other:?}")); + // Magic number to avoid ICEing. + 1 + } }); for (value, _) in targets.iter() { diff --git a/tests/crashes/140850.rs b/tests/crashes/140850.rs index fd26097deda00..92ee389facdbf 100644 --- a/tests/crashes/140850.rs +++ b/tests/crashes/140850.rs @@ -1,6 +1,6 @@ //@ known-bug: #140850 //@ compile-flags: -Zvalidate-mir -fn A() -> impl { +fn A() -> impl Copy { while A() {} loop {} } diff --git a/tests/crashes/137916.rs b/tests/ui/coroutine/non-send-dyn-send-ice.rs similarity index 54% rename from tests/crashes/137916.rs rename to tests/ui/coroutine/non-send-dyn-send-ice.rs index b25e7b200d959..275f7dc3430f1 100644 --- a/tests/crashes/137916.rs +++ b/tests/ui/coroutine/non-send-dyn-send-ice.rs @@ -1,9 +1,11 @@ -//@ known-bug: #137916 +//! Regression test for ICE #137916 //@ edition: 2021 +//@ compile-flags: -Zvalidate-mir + use std::ptr::null; async fn a() -> Box { - Box::new(async { + Box::new(async { //~ ERROR future cannot be sent between threads safely let non_send = null::<()>(); &non_send; async {}.await diff --git a/tests/ui/coroutine/non-send-dyn-send-ice.stderr b/tests/ui/coroutine/non-send-dyn-send-ice.stderr new file mode 100644 index 0000000000000..eeb72fa1bc774 --- /dev/null +++ b/tests/ui/coroutine/non-send-dyn-send-ice.stderr @@ -0,0 +1,23 @@ +error: future cannot be sent between threads safely + --> $DIR/non-send-dyn-send-ice.rs:8:5 + | +LL | / Box::new(async { +LL | | let non_send = null::<()>(); +LL | | &non_send; +LL | | async {}.await +LL | | }) + | |______^ future created by async block is not `Send` + | + = help: within `{async block@$DIR/non-send-dyn-send-ice.rs:8:14: 8:19}`, the trait `Send` is not implemented for `*const ()` +note: future is not `Send` as this value is used across an await + --> $DIR/non-send-dyn-send-ice.rs:11:18 + | +LL | let non_send = null::<()>(); + | -------- has type `*const ()` which is not `Send` +LL | &non_send; +LL | async {}.await + | ^^^^^ await occurs here, with `non_send` maybe used later + = note: required for the cast from `Box<{async block@$DIR/non-send-dyn-send-ice.rs:8:14: 8:19}>` to `Box` + +error: aborting due to 1 previous error + diff --git a/tests/crashes/126680.rs b/tests/ui/type-alias-impl-trait/branch-closure-parameter.rs similarity index 80% rename from tests/crashes/126680.rs rename to tests/ui/type-alias-impl-trait/branch-closure-parameter.rs index dcb6ccad6b422..18ca7e01ce562 100644 --- a/tests/crashes/126680.rs +++ b/tests/ui/type-alias-impl-trait/branch-closure-parameter.rs @@ -1,5 +1,6 @@ -//@ known-bug: rust-lang/rust#126680 +//! Regression test for #126680 //@ compile-flags: -Zvalidate-mir + #![feature(type_alias_impl_trait)] type Bar = impl std::fmt::Display; @@ -10,7 +11,7 @@ struct A { } #[define_opaque(Bar)] -fn foo() -> A { +fn foo() -> A { //~ ERROR item does not constrain `Bar::{opaque#0}` A { func: |check, b| { if check { diff --git a/tests/ui/type-alias-impl-trait/branch-closure-parameter.stderr b/tests/ui/type-alias-impl-trait/branch-closure-parameter.stderr new file mode 100644 index 0000000000000..aa37270c2f58e --- /dev/null +++ b/tests/ui/type-alias-impl-trait/branch-closure-parameter.stderr @@ -0,0 +1,15 @@ +error: item does not constrain `Bar::{opaque#0}` + --> $DIR/branch-closure-parameter.rs:14:4 + | +LL | fn foo() -> A { + | ^^^ + | + = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` +note: this opaque type is supposed to be constrained + --> $DIR/branch-closure-parameter.rs:5:12 + | +LL | type Bar = impl std::fmt::Display; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 8a25163a240be63d89e36dbfda7191014f1739c4 Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Tue, 11 Nov 2025 20:12:52 +0000 Subject: [PATCH 2/3] Remove test made obsolete by MCP#838. --- tests/crashes/project-to-simd-array-field.rs | 33 -------------------- 1 file changed, 33 deletions(-) delete mode 100644 tests/crashes/project-to-simd-array-field.rs diff --git a/tests/crashes/project-to-simd-array-field.rs b/tests/crashes/project-to-simd-array-field.rs deleted file mode 100644 index 6dc916c41dbd5..0000000000000 --- a/tests/crashes/project-to-simd-array-field.rs +++ /dev/null @@ -1,33 +0,0 @@ -//@ known-bug: #137108 -//@compile-flags: -Copt-level=3 - -// If you fix this, put it in the corresponding codegen test, -// not in a UI test like the readme says. - -#![crate_type = "lib"] - -#![feature(repr_simd, core_intrinsics)] - -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -#[repr(simd)] -struct i32x3([i32; 3]); - -const _: () = { assert!(size_of::() == 16) }; - -#[inline(always)] -fn to_array3(a: i32x3) -> [i32; 3] { - a.0 -} - -// CHECK-LABEL: simd_add_self_then_return_array_packed( -// CHECK-SAME: ptr{{.+}}sret{{.+}}%[[RET:.+]], -// CHECK-SAME: ptr{{.+}}%a) -#[no_mangle] -pub fn simd_add_self_then_return_array_packed(a: i32x3) -> [i32; 3] { - // CHECK: %[[T1:.+]] = load <3 x i32>, ptr %a - // CHECK: %[[T2:.+]] = shl <3 x i32> %[[T1]], - // CHECK: store <3 x i32> %[[T2]], ptr %[[RET]] - let b = unsafe { core::intrinsics::simd::simd_add(a, a) }; - to_array3(b) -} From 58d5c3019224771bdc61291da6201c52f09133ed Mon Sep 17 00:00:00 2001 From: Camille Gillot Date: Tue, 11 Nov 2025 22:11:58 +0000 Subject: [PATCH 3/3] Flush delayed bugs when exiting miri. --- src/tools/miri/src/bin/miri.rs | 7 ++++++ .../miri/tests/panic/mir-validation.stderr | 25 ++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 920fc29481916..152a41de1d09c 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -329,6 +329,13 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls { } fn exit(exit_code: i32) -> ! { + // MIR validation uses delayed bugs. Flush them as we won't return for `run_compiler` to do it. + ty::tls::with_opt(|opt_tcx| { + if let Some(tcx) = opt_tcx { + tcx.dcx().flush_delayed() + } + }); + // Drop the tracing guard before exiting, so tracing calls are flushed correctly. deinit_loggers(); // Make sure the supervisor knows about the exit code. diff --git a/src/tools/miri/tests/panic/mir-validation.stderr b/src/tools/miri/tests/panic/mir-validation.stderr index 1d40c93d709e6..700b4995f74f8 100644 --- a/src/tools/miri/tests/panic/mir-validation.stderr +++ b/src/tools/miri/tests/panic/mir-validation.stderr @@ -1,28 +1,23 @@ -error: internal compiler error: compiler/rustc_mir_transform/src/validate.rs:LL:CC: broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]: +note: no errors encountered even though delayed bugs were created + + +error: internal compiler error: broken MIR in Item(DefId) (after phase change to runtime-optimized) at bb0[1]: place (*(_2.0: *mut i32)) has deref as a later projection (it is only permitted as the first projection) --> tests/panic/mir-validation.rs:LL:CC | LL | *(tuple.0) = 1; | ^^^^^^^^^^^^^^ - - -thread 'rustc' ($TID) panicked at compiler/rustc_mir_transform/src/validate.rs:LL:CC: -Box -stack backtrace: + | + + --> tests/panic/mir-validation.rs:LL:CC + | +LL | *(tuple.0) = 1; + | ^^^^^^^^^^^^^^ query stack during panic: -#0 [optimized_mir] optimizing MIR for `main` end of query stack - -Miri caused an ICE during evaluation. Here's the interpreter backtrace at the time of the panic: - --> RUSTLIB/core/src/ops/function.rs:LL:CC - | -LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - error: aborting due to 1 previous error