Don't ICE when pattern matching packed structs
This commit is contained in:
parent
21b1bd69b0
commit
870a6dc230
2 changed files with 24 additions and 2 deletions
|
@ -482,7 +482,12 @@ pub fn const_field<'tcx>(
|
|||
trace!("const_field: {:?}, {:?}", field, value);
|
||||
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
|
||||
// get the operand again
|
||||
let op = ecx.eval_const_to_op(value, None).unwrap();
|
||||
let mut op = ecx.eval_const_to_op(value, None).unwrap();
|
||||
// adjust the alignment of `op` to the one of the allocation, since it may be a field of a
|
||||
// packed struct and thus end up causing an alignment error if we read from it.
|
||||
if let ConstValue::ByRef(_, alloc) = value.val {
|
||||
op.force_alignment(alloc.align);
|
||||
}
|
||||
// downcast
|
||||
let down = match variant {
|
||||
None => op,
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use rustc::{mir, ty};
|
||||
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx};
|
||||
use rustc::ty::layout::{
|
||||
self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx, Align,
|
||||
};
|
||||
|
||||
use rustc::mir::interpret::{
|
||||
GlobalId, AllocId, CheckInAllocMsg,
|
||||
|
@ -177,6 +179,21 @@ impl<'tcx, Tag> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, Tag> OpTy<'tcx, Tag> {
|
||||
/// This function exists solely for pattern matching. If we pattern match a packed struct with
|
||||
/// an ADT field, the constant representing that field will have lost the information about the
|
||||
/// packedness. We could clone the allocation and adjust the alignment, but that seems wasteful,
|
||||
/// since the alignment is already encoded in the allocation. We know it is alright, because
|
||||
/// validation checked everything before the initial constant entered match checking.
|
||||
pub(crate) fn force_alignment(&mut self, align: Align) {
|
||||
if let Operand::Indirect(mplace) = &mut self.op {
|
||||
if align < mplace.align {
|
||||
mplace.align = align;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag>
|
||||
{
|
||||
#[inline]
|
||||
|
|
Loading…
Reference in a new issue