.iter_enumerated()
.all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));
- let mut niche_filling_layout = None;
-
// Niche-filling enum optimization.
if !def.repr.inhibit_enum_layout_opt() && no_explicit_discriminants {
let mut dataful_variant = None;
let largest_niche =
Niche::from_scalar(dl, offset, niche_scalar.clone());
- niche_filling_layout = Some(Layout {
+ return Ok(tcx.intern_layout(Layout {
variants: Variants::Multiple {
tag: niche_scalar,
tag_encoding: TagEncoding::Niche {
largest_niche,
size,
align,
- });
+ }));
}
}
}
let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag.clone());
- let tagged_layout = Layout {
+ tcx.intern_layout(Layout {
variants: Variants::Multiple {
tag,
tag_encoding: TagEncoding::Direct,
abi,
align,
size,
- };
-
- let best_layout = match (tagged_layout, niche_filling_layout) {
- (tagged_layout, Some(niche_filling_layout)) => {
- // Pick the smaller layout; otherwise,
- // pick the layout with the larger niche; otherwise,
- // pick tagged as it has simpler codegen.
- cmp::min_by_key(tagged_layout, niche_filling_layout, |layout| {
- let niche_size =
- layout.largest_niche.as_ref().map_or(0, |n| n.available(dl));
- (layout.size, cmp::Reverse(niche_size))
- })
- }
- (tagged_layout, None) => tagged_layout,
- };
-
- tcx.intern_layout(best_layout)
+ })
}
// Types with no meaningful known layout.
}
fn pointee_info_at(this: TyAndLayout<'tcx>, cx: &C, offset: Size) -> Option<PointeeInfo> {
- match this.ty.kind {
+ let addr_space_of_ty = |ty: Ty<'tcx>| {
+ if ty.is_fn() { cx.data_layout().instruction_address_space } else { AddressSpace::DATA }
+ };
+
+ let pointee_info = match this.ty.kind {
ty::RawPtr(mt) if offset.bytes() == 0 => {
cx.layout_of(mt.ty).to_result().ok().map(|layout| PointeeInfo {
size: layout.size,
align: layout.align.abi,
safe: None,
+ address_space: addr_space_of_ty(mt.ty),
+ })
+ }
+ ty::FnPtr(fn_sig) if offset.bytes() == 0 => {
+ cx.layout_of(cx.tcx().mk_fn_ptr(fn_sig)).to_result().ok().map(|layout| {
+ PointeeInfo {
+ size: layout.size,
+ align: layout.align.abi,
+ safe: None,
+ address_space: cx.data_layout().instruction_address_space,
+ }
})
}
-
ty::Ref(_, ty, mt) if offset.bytes() == 0 => {
+ let address_space = addr_space_of_ty(ty);
let tcx = cx.tcx();
let is_freeze = ty.is_freeze(tcx.at(DUMMY_SP), cx.param_env());
let kind = match mt {
size: layout.size,
align: layout.align.abi,
safe: Some(kind),
+ address_space,
})
}
result = field.to_result().ok().and_then(|field| {
if ptr_end <= field_start + field.size {
// We found the right field, look inside it.
- field.pointee_info_at(cx, offset - field_start)
+ let field_info =
+ field.pointee_info_at(cx, offset - field_start);
+ field_info
} else {
None
}
result
}
- }
+ };
+
+ debug!(
+ "pointee_info_at (offset={:?}, type kind: {:?}) => {:?}",
+ offset, this.ty.kind, pointee_info
+ );
+
+ pointee_info
}
}