diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 5a9018a62c574..8a4df46d9d752 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) { @@ -1637,7 +1636,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 +