tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value)))
};
let scalar_pair = |a: Scalar, b: Scalar| {
- let align = a.value.align(dl).max(b.value.align(dl)).max(dl.aggregate_align);
- let b_offset = a.value.size(dl).abi_align(b.value.align(dl));
- let size = (b_offset + b.value.size(dl)).abi_align(align);
+ let b_align = b.value.align(dl);
+ let align = a.value.align(dl).max(b_align).max(dl.aggregate_align);
+ let b_offset = a.value.size(dl).align_to(b_align.abi);
+ let size = (b_offset + b.value.size(dl)).align_to(align.abi);
LayoutDetails {
variants: Variants::Single { index: VariantIdx::new(0) },
fields: FieldPlacement::Arbitrary {
AlwaysSized,
/// A univariant, the last field of which may be coerced to unsized.
MaybeUnsized,
- /// A univariant, but with a prefix of an arbitrary size & alignment (e.g. enum tag).
- Prefixed(Size, AbiAndPrefAlign),
+ /// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag).
+ Prefixed(Size, Align),
}
let univariant_uninterned = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| {
bug!("struct cannot be packed and aligned");
}
- let pack = {
- let pack = repr.pack as u64;
- AbiAndPrefAlign::from_bytes(pack, pack).unwrap()
- };
+ let pack = Align::from_bytes(repr.pack as u64).unwrap();
let mut align = if packed {
dl.i8_align
let mut optimize = !repr.inhibit_struct_field_reordering_opt();
if let StructKind::Prefixed(_, align) = kind {
- optimize &= align.abi() == 1;
+ optimize &= align.bytes() == 1;
}
if optimize {
};
let optimizing = &mut inverse_memory_index[..end];
let field_align = |f: &TyLayout<'_>| {
- if packed { f.align.min(pack).abi() } else { f.align.abi() }
+ if packed { f.align.abi.min(pack) } else { f.align.abi }
};
match kind {
StructKind::AlwaysSized |
let mut offset = Size::ZERO;
if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
- if packed {
- let prefix_align = prefix_align.min(pack);
- align = align.max(prefix_align);
+ let prefix_align = if packed {
+ prefix_align.min(pack)
} else {
- align = align.max(prefix_align);
- }
- offset = prefix_size.abi_align(prefix_align);
+ prefix_align
+ };
+ align = align.max(AbiAndPrefAlign::new(prefix_align));
+ offset = prefix_size.align_to(prefix_align);
}
for &i in &inverse_memory_index {
}
// Invariant: offset < dl.obj_size_bound() <= 1<<61
- if packed {
- let field_pack = field.align.min(pack);
- offset = offset.abi_align(field_pack);
- align = align.max(field_pack);
- }
- else {
- offset = offset.abi_align(field.align);
- align = align.max(field.align);
- }
+ let field_align = if packed {
+ field.align.min(AbiAndPrefAlign::new(pack))
+ } else {
+ field.align
+ };
+ offset = offset.align_to(field_align.abi);
+ align = align.max(field_align);
debug!("univariant offset: {:?} field: {:#?}", offset, field);
offsets[i as usize] = offset;
if repr.align > 0 {
let repr_align = repr.align as u64;
- align = align.max(AbiAndPrefAlign::from_bytes(repr_align, repr_align).unwrap());
+ align = align.max(AbiAndPrefAlign::new(Align::from_bytes(repr_align).unwrap()));
debug!("univariant repr_align: {:?}", repr_align);
}
memory_index = inverse_memory_index;
}
- let size = min_size.abi_align(align);
+ let size = min_size.align_to(align.abi);
let mut abi = Abi::Aggregate { sized };
// Unpack newtype ABIs and find scalar pairs.
(Some((i, field)), None, None) => {
// Field fills the struct and it has a scalar or scalar pair ABI.
if offsets[i].bytes() == 0 &&
- align.abi() == field.align.abi() &&
+ align.abi == field.align.abi &&
size == field.size {
match field.abi {
// For plain scalars, or vectors of them, we can't unpack
let size = element.size.checked_mul(count, dl)
.ok_or(LayoutError::SizeOverflow(ty))?;
let align = dl.vector_align(size);
- let size = size.abi_align(align);
+ let size = size.align_to(align.abi);
tcx.intern_layout(LayoutDetails {
variants: Variants::Single { index: VariantIdx::new(0) },
bug!("Union cannot be packed and aligned");
}
- let pack = {
- let pack = def.repr.pack as u64;
- AbiAndPrefAlign::from_bytes(pack, pack).unwrap()
- };
+ let pack = Align::from_bytes(def.repr.pack as u64).unwrap();
let mut align = if packed {
dl.i8_align
if def.repr.align > 0 {
let repr_align = def.repr.align as u64;
align = align.max(
- AbiAndPrefAlign::from_bytes(repr_align, repr_align).unwrap());
+ AbiAndPrefAlign::new(Align::from_bytes(repr_align).unwrap()));
}
let optimize = !def.repr.inhibit_union_abi_opt();
for field in &variants[index] {
assert!(!field.is_unsized());
- if packed {
- let field_pack = field.align.min(pack);
- align = align.max(field_pack);
+ let field_align = if packed {
+ field.align.min(AbiAndPrefAlign::new(pack))
} else {
- align = align.max(field.align);
- }
+ field.align
+ };
+ align = align.max(field_align);
// If all non-ZST fields have the same ABI, forward this ABI
if optimize && !field.is_zst() {
fields: FieldPlacement::Union(variants[index].len()),
abi,
align,
- size: size.abi_align(align)
+ size: size.align_to(align.abi)
}));
}
// A variant is absent if it's uninhabited and only has ZST fields.
// Present uninhabited variants only require space for their fields,
- // but *not* an encoding of the discriminant (e.g. a tag value).
+ // but *not* an encoding of the discriminant (e.g., a tag value).
// See issue #49298 for more details on the need to leave space
// for non-ZST uninhabited data (mostly partial initialization).
let absent = |fields: &[TyLayout<'_>]| {
let mut size = Size::ZERO;
// We're interested in the smallest alignment, so start large.
- let mut start_align = AbiAndPrefAlign::from_bytes(256, 256).unwrap();
- assert_eq!(Integer::for_abi_align(dl, start_align), None);
+ let mut start_align = Align::from_bytes(256).unwrap();
+ assert_eq!(Integer::for_align(dl, start_align), None);
// repr(C) on an enum tells us to make a (tag, union) layout,
// so we need to grow the prefix alignment to be at least
// the alignment of the union. (This value is used both for
// determining the alignment of the overall enum, and the
// determining the alignment of the payload after the tag.)
- let mut prefix_align = min_ity.align(dl);
+ let mut prefix_align = min_ity.align(dl).abi;
if def.repr.c() {
for fields in &variants {
for field in fields {
- prefix_align = prefix_align.max(field.align);
+ prefix_align = prefix_align.max(field.align.abi);
}
}
}
// Find the first field we can't move later
// to make room for a larger discriminant.
for field in st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) {
- if !field.is_zst() || field.align.abi() != 1 {
- start_align = start_align.min(field.align);
+ if !field.is_zst() || field.align.abi.bytes() != 1 {
+ start_align = start_align.min(field.align.abi);
break;
}
}
}).collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
// Align the maximum variant size to the largest alignment.
- size = size.abi_align(align);
+ size = size.align_to(align.abi);
if size.bytes() >= dl.obj_size_bound() {
return Err(LayoutError::SizeOverflow(ty));
let mut ity = if def.repr.c() || def.repr.int.is_some() {
min_ity
} else {
- Integer::for_abi_align(dl, start_align).unwrap_or(min_ity)
+ Integer::for_align(dl, start_align).unwrap_or(min_ity)
};
// If the alignment is not larger than the chosen discriminant size,
}
ty::Bound(..) |
+ ty::Placeholder(..) |
ty::UnnormalizedProjection(..) |
ty::GeneratorWitness(..) |
ty::Infer(_) => {
let type_desc = format!("{:?}", layout.ty);
self.tcx.sess.code_stats.borrow_mut().record_type_size(kind,
type_desc,
- layout.align,
+ layout.align.abi,
layout.size,
packed,
opt_discr_size,
name: name.to_string(),
offset: offset.bytes(),
size: field_layout.size.bytes(),
- align: field_layout.align.abi(),
+ align: field_layout.align.abi.bytes(),
}
}
}
}).collect();
session::VariantInfo {
- name: n.map(|n|n.to_string()),
+ name: n.map(|n| n.to_string()),
kind: if layout.is_unsized() {
session::SizeKind::Min
} else {
session::SizeKind::Exact
},
- align: layout.align.abi(),
+ align: layout.align.abi.bytes(),
size: if min_size.bytes() == 0 {
layout.size.bytes()
} else {
}
}
-/// Type size "skeleton", i.e. the only information determining a type's size.
+/// Type size "skeleton", i.e., the only information determining a type's size.
/// While this is conservative, (aside from constant sizes, only pointers,
/// newtypes thereof and null pointer optimized enums are allowed), it is
/// enough to statically check common use cases of transmute.
details
};
- // NB: This recording is normally disabled; when enabled, it
+ // N.B., this recording is normally disabled; when enabled, it
// can however trigger recursive invocations of `layout_of`.
// Therefore, we execute it *after* the main query has
// completed, to avoid problems around recursive structures
details
};
- // NB: This recording is normally disabled; when enabled, it
+ // N.B., this recording is normally disabled; when enabled, it
// can however trigger recursive invocations of `layout_of`.
// Therefore, we execute it *after* the main query has
// completed, to avoid problems around recursive structures
assert!(i < this.fields.count());
// Reuse the fat *T type as its own thin pointer data field.
- // This provides information about e.g. DST struct pointees
+ // This provides information about e.g., DST struct pointees
// (which may have no non-DST form), and will work as long
// as the `Abi` or `FieldPlacement` is checked by users.
if i == 0 {
}
ty::Projection(_) | ty::UnnormalizedProjection(..) | ty::Bound(..) |
- ty::Opaque(..) | ty::Param(_) | ty::Infer(_) | ty::Error => {
+ ty::Placeholder(..) | ty::Opaque(..) | ty::Param(_) | ty::Infer(_) |
+ ty::Error => {
bug!("TyLayout::field_type: unexpected type `{}`", this.ty)
}
})
Abi::ScalarPair(ref a, ref b) => {
// HACK(nox): We iter on `b` and then `a` because `max_by_key`
// returns the last maximum.
- let niche = iter::once((b, a.value.size(self).abi_align(b.value.align(self))))
+ let niche = iter::once(
+ (b, a.value.size(self).align_to(b.value.align(self).abi))
+ )
.chain(iter::once((a, Size::ZERO)))
.filter_map(|(scalar, offset)| scalar_niche(scalar, offset))
.max_by_key(|niche| niche.available);
Pointer
});
-impl<'gcx> HashStable<StableHashingContext<'gcx>> for AbiAndPrefAlign {
+impl_stable_hash_for!(struct ::ty::layout::AbiAndPrefAlign {
+ abi,
+ pref
+});
+
+impl<'gcx> HashStable<StableHashingContext<'gcx>> for Align {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
- self.abi().hash_stable(hcx, hasher);
- self.pref().hash_stable(hcx, hasher);
+ self.bytes().hash_stable(hcx, hasher);
}
}