Skip to content

Commit d490c34

Browse files
committed
Don't ICE in subslice pattern const-eval
1 parent 12307b3 commit d490c34

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

src/librustc_mir/interpret/operand.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -444,13 +444,27 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
444444
Field(field, _) => self.operand_field(base, field.index() as u64)?,
445445
Downcast(_, variant) => self.operand_downcast(base, variant)?,
446446
Deref => self.deref_operand(base)?.into(),
447-
Subslice { .. } | ConstantIndex { .. } | Index(_) => if base.layout.is_zst() {
447+
ConstantIndex { .. } | Index(_) if base.layout.is_zst() => {
448448
OpTy {
449449
op: Operand::Immediate(Scalar::zst().into()),
450450
// the actual index doesn't matter, so we just pick a convenient one like 0
451451
layout: base.layout.field(self, 0)?,
452452
}
453-
} else {
453+
}
454+
Subslice { from, to, from_end } if base.layout.is_zst() => {
455+
let elem_ty = if let ty::Array(elem_ty, _) = base.layout.ty.kind {
456+
elem_ty
457+
} else {
458+
bug!("slices shouldn't be zero-sized");
459+
};
460+
assert!(!from_end, "arrays shouldn't be subsliced from the end");
461+
462+
OpTy {
463+
op: Operand::Immediate(Scalar::zst().into()),
464+
layout: self.layout_of(self.tcx.mk_array(elem_ty, (to - from) as u64))?,
465+
}
466+
}
467+
Subslice { .. } | ConstantIndex { .. } | Index(_) => {
454468
// The rest should only occur as mplace, we do not use Immediates for types
455469
// allowing such operations. This matches place_projection forcing an allocation.
456470
let mplace = base.assert_mem_place();

src/librustc_mir/interpret/place.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,10 @@ where
455455
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
456456
let len = base.len(self)?; // also asserts that we have a type where this makes sense
457457
let actual_to = if from_end {
458-
assert!(from <= len - to);
458+
if from + to > len {
459+
// This can only be reached in ConstProp and non-rustc-MIR.
460+
throw_ub!(BoundsCheckFailed { len: len as u64, index: from as u64 + to as u64 });
461+
}
459462
len - to
460463
} else {
461464
to
@@ -523,7 +526,11 @@ where
523526
from_end,
524527
} => {
525528
let n = base.len(self)?;
526-
assert!(n >= min_length as u64);
529+
if n < min_length as u64 {
530+
// This can only be reached in ConstProp and non-rustc-MIR.
531+
throw_ub!(BoundsCheckFailed { len: min_length as u64, index: n as u64 });
532+
}
533+
assert!(offset < min_length);
527534

528535
let index = if from_end {
529536
n - u64::from(offset)

0 commit comments

Comments
 (0)