Don't ICE in subslice pattern const-eval
This commit is contained in:
parent
12307b3b08
commit
d490c34086
@ -444,13 +444,27 @@ pub fn operand_projection(
|
||||
Field(field, _) => self.operand_field(base, field.index() as u64)?,
|
||||
Downcast(_, variant) => self.operand_downcast(base, variant)?,
|
||||
Deref => self.deref_operand(base)?.into(),
|
||||
Subslice { .. } | ConstantIndex { .. } | Index(_) => if base.layout.is_zst() {
|
||||
ConstantIndex { .. } | Index(_) if base.layout.is_zst() => {
|
||||
OpTy {
|
||||
op: Operand::Immediate(Scalar::zst().into()),
|
||||
// the actual index doesn't matter, so we just pick a convenient one like 0
|
||||
layout: base.layout.field(self, 0)?,
|
||||
}
|
||||
} else {
|
||||
}
|
||||
Subslice { from, to, from_end } if base.layout.is_zst() => {
|
||||
let elem_ty = if let ty::Array(elem_ty, _) = base.layout.ty.kind {
|
||||
elem_ty
|
||||
} else {
|
||||
bug!("slices shouldn't be zero-sized");
|
||||
};
|
||||
assert!(!from_end, "arrays shouldn't be subsliced from the end");
|
||||
|
||||
OpTy {
|
||||
op: Operand::Immediate(Scalar::zst().into()),
|
||||
layout: self.layout_of(self.tcx.mk_array(elem_ty, (to - from) as u64))?,
|
||||
}
|
||||
}
|
||||
Subslice { .. } | ConstantIndex { .. } | Index(_) => {
|
||||
// The rest should only occur as mplace, we do not use Immediates for types
|
||||
// allowing such operations. This matches place_projection forcing an allocation.
|
||||
let mplace = base.assert_mem_place();
|
||||
|
@ -455,7 +455,10 @@ pub fn mplace_subslice(
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
let len = base.len(self)?; // also asserts that we have a type where this makes sense
|
||||
let actual_to = if from_end {
|
||||
assert!(from <= len - to);
|
||||
if from + to > len {
|
||||
// This can only be reached in ConstProp and non-rustc-MIR.
|
||||
throw_ub!(BoundsCheckFailed { len: len as u64, index: from as u64 + to as u64 });
|
||||
}
|
||||
len - to
|
||||
} else {
|
||||
to
|
||||
@ -523,7 +526,11 @@ pub fn mplace_projection(
|
||||
from_end,
|
||||
} => {
|
||||
let n = base.len(self)?;
|
||||
assert!(n >= min_length as u64);
|
||||
if n < min_length as u64 {
|
||||
// This can only be reached in ConstProp and non-rustc-MIR.
|
||||
throw_ub!(BoundsCheckFailed { len: min_length as u64, index: n as u64 });
|
||||
}
|
||||
assert!(offset < min_length);
|
||||
|
||||
let index = if from_end {
|
||||
n - u64::from(offset)
|
||||
|
Loading…
Reference in New Issue
Block a user