diff --git a/compiler/rustc_mir_transform/src/impossible_predicates.rs b/compiler/rustc_mir_transform/src/impossible_predicates.rs index 88486f6baddad..d099fc3b9ddeb 100644 --- a/compiler/rustc_mir_transform/src/impossible_predicates.rs +++ b/compiler/rustc_mir_transform/src/impossible_predicates.rs @@ -36,7 +36,7 @@ use crate::pass_manager::MirPass; pub(crate) struct ImpossiblePredicates; -fn has_impossible_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> bool { +pub(crate) fn has_impossible_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx); tracing::trace!(?predicates); let predicates = diff --git a/compiler/rustc_mir_transform/src/trivial_const.rs b/compiler/rustc_mir_transform/src/trivial_const.rs index 2a924fa408c03..25d15c12a7b3b 100644 --- a/compiler/rustc_mir_transform/src/trivial_const.rs +++ b/compiler/rustc_mir_transform/src/trivial_const.rs @@ -59,6 +59,14 @@ where return None; } + // If there are impossible predicates then MIR passes will replace the body with + // `unreachable` causing const eval errors when trying to evaluate the body. For + // now we avoid using trivial consts for such bodies so that the behaviour doesn't + // change. + if crate::impossible_predicates::has_impossible_predicates(tcx, def.into()) { + return None; + } + if !tcx.opaque_types_defined_by(def).is_empty() { return None; } diff --git a/tests/ui/traits/trivial-const-with-impossible-bounds.rs b/tests/ui/traits/trivial-const-with-impossible-bounds.rs new file mode 100644 index 0000000000000..83db312d225da --- /dev/null +++ b/tests/ui/traits/trivial-const-with-impossible-bounds.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +struct Dummy; +impl Dummy where for<'a> &'a mut i32: Copy { + const C: usize = 1; //~ ERROR entering unreachable code +} + +fn foo() where for<'a> &'a mut i32: Copy { + if let Dummy::C = 1 {} +} diff --git a/tests/ui/traits/trivial-const-with-impossible-bounds.stderr b/tests/ui/traits/trivial-const-with-impossible-bounds.stderr new file mode 100644 index 0000000000000..c5cf6626cc7a1 --- /dev/null +++ b/tests/ui/traits/trivial-const-with-impossible-bounds.stderr @@ -0,0 +1,9 @@ +error[E0080]: entering unreachable code + --> $DIR/trivial-const-with-impossible-bounds.rs:5:5 + | +LL | const C: usize = 1; + | ^^^^^^^^^^^^^^^^^^^ evaluation of `Dummy::C` failed here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`.