Do not ICE on invalid consts when walking mono-reachable blocks
This commit is contained in:
parent
ef8b9dcf23
commit
82cc02a60b
@ -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,
|
||||||
|
23
tests/ui/consts/mono-reachable-invalid-const.rs
Normal file
23
tests/ui/consts/mono-reachable-invalid-const.rs
Normal 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();
|
||||||
|
}
|
29
tests/ui/consts/mono-reachable-invalid-const.stderr
Normal file
29
tests/ui/consts/mono-reachable-invalid-const.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user