_ if !field.is_unsized() => return simple(),
ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(),
ty::Adt(def, _) => {
- if def.repr.packed() {
+ if def.repr().packed() {
// FIXME(eddyb) generalize the adjustment when we
// start supporting packing to larger alignments.
assert_eq!(self.layout.align.abi.bytes(), 1);
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
{
base = elem.0 + 1;
- self.codegen_consume(
+ let cg_base = self.codegen_consume(
bx,
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
- )
- .deref(bx.cx())
+ );
+
+ // a box with a non-zst allocator should not be directly dereferenced
+ if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
+ let ptr = cg_base.extract_field(bx, 0).extract_field(bx, 0);
+
+ ptr.deref(bx.cx())
+ } else {
+ cg_base.deref(bx.cx())
+ }
} else {
bug!("using operand local {:?} as place", place_ref);
}
};
for elem in place_ref.projection[base..].iter() {
cg_base = match elem.clone() {
- mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
+ mir::ProjectionElem::Deref => {
+ // a box with a non-zst allocator should not be directly dereferenced
+ if cg_base.layout.ty.is_box() && !cg_base.layout.field(cx, 1).is_zst() {
+ let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);
+
+ bx.load_operand(ptr).deref(bx.cx())
+ } else {
+ bx.load_operand(cg_base).deref(bx.cx())
+ }
+ }
mir::ProjectionElem::Field(ref field, _) => {
cg_base.project_field(bx, field.index())
}