Do not ICE on invalid consts when walking mono-reachable blocks

This commit is contained in:
Ben Kimock 2024-04-26 22:51:16 -04:00
parent ef8b9dcf23
commit 82cc02a60b
3 changed files with 55 additions and 6 deletions

View File

@ -701,10 +701,7 @@ fn try_const_mono_switchint<'a>(
env, env,
crate::ty::EarlyBinder::bind(constant.const_), crate::ty::EarlyBinder::bind(constant.const_),
); );
let Some(bits) = mono_literal.try_eval_bits(tcx, env) else { mono_literal.try_eval_bits(tcx, env)
bug!("Couldn't evaluate constant {:?} in mono {:?}", constant, instance);
};
bits
}; };
let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else { let TerminatorKind::SwitchInt { discr, targets } = &block.terminator().kind else {
@ -714,7 +711,7 @@ fn try_const_mono_switchint<'a>(
// If this is a SwitchInt(const _), then we can just evaluate the constant and return. // If this is a SwitchInt(const _), then we can just evaluate the constant and return.
let discr = match discr { let discr = match discr {
Operand::Constant(constant) => { Operand::Constant(constant) => {
let bits = eval_mono_const(constant); let bits = eval_mono_const(constant)?;
return Some((bits, targets)); return Some((bits, targets));
} }
Operand::Move(place) | Operand::Copy(place) => place, Operand::Move(place) | Operand::Copy(place) => place,
@ -748,7 +745,7 @@ fn try_const_mono_switchint<'a>(
match rvalue { match rvalue {
Rvalue::NullaryOp(NullOp::UbChecks, _) => Some((tcx.sess.ub_checks() as u128, targets)), Rvalue::NullaryOp(NullOp::UbChecks, _) => Some((tcx.sess.ub_checks() as u128, targets)),
Rvalue::Use(Operand::Constant(constant)) => { Rvalue::Use(Operand::Constant(constant)) => {
let bits = eval_mono_const(constant); let bits = eval_mono_const(constant)?;
Some((bits, targets)) Some((bits, targets))
} }
_ => None, _ => None,

View File

@ -0,0 +1,23 @@
//@ build-fail
struct Bar<const BITS: usize>;
impl<const BITS: usize> Bar<BITS> {
const ASSERT: bool = {
let b = std::convert::identity(1);
["oops"][b]; //~ ERROR evaluation of `Bar::<0>::ASSERT` failed
true
};
fn assert() {
let val = Self::ASSERT;
if val {
std::convert::identity(val);
}
}
}
fn main() {
Bar::<0>::assert();
}

View File

@ -0,0 +1,29 @@
error[E0080]: evaluation of `Bar::<0>::ASSERT` failed
--> $DIR/mono-reachable-invalid-const.rs:8:9
|
LL | ["oops"][b];
| ^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
note: erroneous constant encountered
--> $DIR/mono-reachable-invalid-const.rs:13:19
|
LL | let val = Self::ASSERT;
| ^^^^^^^^^^^^
note: erroneous constant encountered
--> $DIR/mono-reachable-invalid-const.rs:13:19
|
LL | let val = Self::ASSERT;
| ^^^^^^^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
note: the above error was encountered while instantiating `fn Bar::<0>::assert`
--> $DIR/mono-reachable-invalid-const.rs:22:5
|
LL | Bar::<0>::assert();
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0080`.