Skip to content

Commit 3bdd7f8

Browse files
committed
Auto merge of #156934 - saethlin:impossible-bounds-check, r=BoxyUwU
Add a check for impossible predicates to trivial_const The problem here is that trivial consts bypass the MIR pass which replaces bodies with `unreachable` when there are false global bounds. see #147721 (comment). This fixes the problem, but it is a bit hacky. But maybe all the handling of false global bounds is hacky?
2 parents a1e52fc + 8dc9f9a commit 3bdd7f8

4 files changed

Lines changed: 28 additions & 1 deletion

File tree

compiler/rustc_mir_transform/src/impossible_predicates.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use crate::pass_manager::MirPass;
3636

3737
pub(crate) struct ImpossiblePredicates;
3838

39-
fn has_impossible_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
39+
pub(crate) fn has_impossible_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
4040
let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx);
4141
tracing::trace!(?predicates);
4242
let predicates =

compiler/rustc_mir_transform/src/trivial_const.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ where
5959
return None;
6060
}
6161

62+
// If there are impossible predicates then MIR passes will replace the body with
63+
// `unreachable` causing const eval errors when trying to evaluate the body. For
64+
// now we avoid using trivial consts for such bodies so that the behaviour doesn't
65+
// change.
66+
if crate::impossible_predicates::has_impossible_predicates(tcx, def.into()) {
67+
return None;
68+
}
69+
6270
if !tcx.opaque_types_defined_by(def).is_empty() {
6371
return None;
6472
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#![crate_type = "lib"]
2+
3+
struct Dummy;
4+
impl Dummy where for<'a> &'a mut i32: Copy {
5+
const C: usize = 1; //~ ERROR entering unreachable code
6+
}
7+
8+
fn foo() where for<'a> &'a mut i32: Copy {
9+
if let Dummy::C = 1 {}
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0080]: entering unreachable code
2+
--> $DIR/trivial-const-with-impossible-bounds.rs:5:5
3+
|
4+
LL | const C: usize = 1;
5+
| ^^^^^^^^^^^^^^^^^^^ evaluation of `Dummy::C` failed here
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)