Skip to content

Commit 0430e74

Browse files
authored
Rollup merge of #124425 - saethlin:ceci-nest-pas-une-ice, r=compiler-errors
Do not ICE on invalid consts when walking mono-reachable blocks The `bug!` here was written under the logic of "this condition is impossible, right?" except that of course, if the compiler is given code that results in an compile error, then the situation is possible. So now we just direct errors into the already-existing path for when we can't do a mono-time optimization.
2 parents aeb4c04 + 82cc02a commit 0430e74

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

Diff for: compiler/rustc_middle/src/mir/mod.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -701,10 +701,7 @@ impl<'tcx> Body<'tcx> {
701701
env,
702702
crate::ty::EarlyBinder::bind(constant.const_),
703703
);
704-
let Some(bits) = mono_literal.try_eval_bits(tcx, env) else {
705-
bug!("Couldn't evaluate constant {:?} in mono {:?}", constant, instance);
706-
};
707-
bits
704+
mono_literal.try_eval_bits(tcx, env)
708705
};
709706

710707
let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else {
@@ -714,7 +711,7 @@ impl<'tcx> Body<'tcx> {
714711
// If this is a SwitchInt(const _), then we can just evaluate the constant and return.
715712
let discr = match discr {
716713
Operand::Constant(constant) => {
717-
let bits = eval_mono_const(constant);
714+
let bits = eval_mono_const(constant)?;
718715
return Some((bits, targets));
719716
}
720717
Operand::Move(place) | Operand::Copy(place) => place,
@@ -748,7 +745,7 @@ impl<'tcx> Body<'tcx> {
748745
match rvalue {
749746
Rvalue::NullaryOp(NullOp::UbChecks, _) => Some((tcx.sess.ub_checks() as u128, targets)),
750747
Rvalue::Use(Operand::Constant(constant)) => {
751-
let bits = eval_mono_const(constant);
748+
let bits = eval_mono_const(constant)?;
752749
Some((bits, targets))
753750
}
754751
_ => None,

Diff for: tests/ui/consts/mono-reachable-invalid-const.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ build-fail
2+
3+
struct Bar<const BITS: usize>;
4+
5+
impl<const BITS: usize> Bar<BITS> {
6+
const ASSERT: bool = {
7+
let b = std::convert::identity(1);
8+
["oops"][b]; //~ ERROR evaluation of `Bar::<0>::ASSERT` failed
9+
true
10+
};
11+
12+
fn assert() {
13+
let val = Self::ASSERT;
14+
if val {
15+
std::convert::identity(val);
16+
}
17+
}
18+
}
19+
20+
21+
fn main() {
22+
Bar::<0>::assert();
23+
}

Diff for: tests/ui/consts/mono-reachable-invalid-const.stderr

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0080]: evaluation of `Bar::<0>::ASSERT` failed
2+
--> $DIR/mono-reachable-invalid-const.rs:8:9
3+
|
4+
LL | ["oops"][b];
5+
| ^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
6+
7+
note: erroneous constant encountered
8+
--> $DIR/mono-reachable-invalid-const.rs:13:19
9+
|
10+
LL | let val = Self::ASSERT;
11+
| ^^^^^^^^^^^^
12+
13+
note: erroneous constant encountered
14+
--> $DIR/mono-reachable-invalid-const.rs:13:19
15+
|
16+
LL | let val = Self::ASSERT;
17+
| ^^^^^^^^^^^^
18+
|
19+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
20+
21+
note: the above error was encountered while instantiating `fn Bar::<0>::assert`
22+
--> $DIR/mono-reachable-invalid-const.rs:22:5
23+
|
24+
LL | Bar::<0>::assert();
25+
| ^^^^^^^^^^^^^^^^^^
26+
27+
error: aborting due to 1 previous error
28+
29+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)