Extract univariant_uninterned as method
This commit is contained in:
parent
fbdff56f4b
commit
c158d1ca0c
1 changed files with 254 additions and 244 deletions
|
@ -215,23 +215,19 @@ pub struct LayoutCx<'tcx, C> {
|
|||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
||||
fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
|
||||
let tcx = self.tcx;
|
||||
let param_env = self.param_env;
|
||||
let dl = self.data_layout();
|
||||
let scalar_unit = |value: Primitive| {
|
||||
let bits = value.size(dl).bits();
|
||||
assert!(bits <= 128);
|
||||
Scalar {
|
||||
value,
|
||||
valid_range: 0..=(!0 >> (128 - bits))
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum StructKind {
|
||||
/// A tuple, closure, or univariant which cannot be coerced to unsized.
|
||||
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, Align),
|
||||
}
|
||||
};
|
||||
let scalar = |value: Primitive| {
|
||||
tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value)))
|
||||
};
|
||||
let scalar_pair = |a: Scalar, b: Scalar| {
|
||||
|
||||
impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
||||
fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutDetails {
|
||||
let dl = self.data_layout();
|
||||
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);
|
||||
|
@ -246,19 +242,14 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
align,
|
||||
size
|
||||
}
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum StructKind {
|
||||
/// A tuple, closure, or univariant which cannot be coerced to unsized.
|
||||
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, Align),
|
||||
}
|
||||
|
||||
let univariant_uninterned = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| {
|
||||
fn univariant_uninterned(&self,
|
||||
ty: Ty<'tcx>,
|
||||
fields: &[TyLayout<'_>],
|
||||
repr: &ReprOptions,
|
||||
kind: StructKind) -> Result<LayoutDetails, LayoutError<'tcx>> {
|
||||
let dl = self.data_layout();
|
||||
let packed = repr.packed();
|
||||
if packed && repr.align > 0 {
|
||||
bug!("struct cannot be packed and aligned");
|
||||
|
@ -426,7 +417,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
} else {
|
||||
((j, b), (i, a))
|
||||
};
|
||||
let pair = scalar_pair(a.clone(), b.clone());
|
||||
let pair = self.scalar_pair(a.clone(), b.clone());
|
||||
let pair_offsets = match pair.fields {
|
||||
FieldPlacement::Arbitrary {
|
||||
ref offsets,
|
||||
|
@ -466,9 +457,26 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
align,
|
||||
size
|
||||
})
|
||||
}
|
||||
|
||||
fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
|
||||
let tcx = self.tcx;
|
||||
let param_env = self.param_env;
|
||||
let dl = self.data_layout();
|
||||
let scalar_unit = |value: Primitive| {
|
||||
let bits = value.size(dl).bits();
|
||||
assert!(bits <= 128);
|
||||
Scalar {
|
||||
value,
|
||||
valid_range: 0..=(!0 >> (128 - bits))
|
||||
}
|
||||
};
|
||||
let scalar = |value: Primitive| {
|
||||
tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value)))
|
||||
};
|
||||
|
||||
let univariant = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| {
|
||||
Ok(tcx.intern_layout(univariant_uninterned(fields, repr, kind)?))
|
||||
Ok(tcx.intern_layout(self.univariant_uninterned(ty, fields, repr, kind)?))
|
||||
};
|
||||
debug_assert!(!ty.has_infer_types());
|
||||
|
||||
|
@ -540,7 +548,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
};
|
||||
|
||||
// Effectively a (ptr, meta) tuple.
|
||||
tcx.intern_layout(scalar_pair(data_ptr, metadata))
|
||||
tcx.intern_layout(self.scalar_pair(data_ptr, metadata))
|
||||
}
|
||||
|
||||
// Arrays and slices.
|
||||
|
@ -605,7 +613,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?
|
||||
}
|
||||
ty::Dynamic(..) | ty::Foreign(..) => {
|
||||
let mut unit = univariant_uninterned(&[], &ReprOptions::default(),
|
||||
let mut unit = self.univariant_uninterned(ty, &[], &ReprOptions::default(),
|
||||
StructKind::AlwaysSized)?;
|
||||
match unit.abi {
|
||||
Abi::Aggregate { ref mut sized } => *sized = false,
|
||||
|
@ -730,7 +738,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
let prefix_tys = substs.prefix_tys(def_id, tcx)
|
||||
.chain(iter::once(substs.discr_ty(tcx)))
|
||||
.chain(promoted_tys);
|
||||
let prefix = univariant_uninterned(
|
||||
let prefix = self.univariant_uninterned(
|
||||
ty,
|
||||
&prefix_tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
|
||||
&ReprOptions::default(),
|
||||
StructKind::AlwaysSized)?;
|
||||
|
@ -787,7 +796,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
})
|
||||
.map(|local| subst_field(info.field_tys[*local]));
|
||||
|
||||
let mut variant = univariant_uninterned(
|
||||
let mut variant = self.univariant_uninterned(
|
||||
ty,
|
||||
&variant_only_tys
|
||||
.map(|ty| self.layout_of(ty))
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
|
@ -1049,7 +1059,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
else { StructKind::AlwaysSized }
|
||||
};
|
||||
|
||||
let mut st = univariant_uninterned(&variants[v], &def.repr, kind)?;
|
||||
let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr, kind)?;
|
||||
st.variants = Variants::Single { index: v };
|
||||
let (start, end) = self.tcx.layout_scalar_valid_range(def.did);
|
||||
match st.abi {
|
||||
|
@ -1128,7 +1138,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
|
||||
let mut align = dl.aggregate_align;
|
||||
let st = variants.iter_enumerated().map(|(j, v)| {
|
||||
let mut st = univariant_uninterned(v,
|
||||
let mut st = self.univariant_uninterned(ty, v,
|
||||
&def.repr, StructKind::AlwaysSized)?;
|
||||
st.variants = Variants::Single { index: j };
|
||||
|
||||
|
@ -1236,7 +1246,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
|
||||
// Create the set of structs that represent each variant.
|
||||
let mut layout_variants = variants.iter_enumerated().map(|(i, field_layouts)| {
|
||||
let mut st = univariant_uninterned(&field_layouts,
|
||||
let mut st = self.univariant_uninterned(ty, &field_layouts,
|
||||
&def.repr, StructKind::Prefixed(min_ity.size(), prefix_align))?;
|
||||
st.variants = Variants::Single { index: i };
|
||||
// Find the first field we can't move later
|
||||
|
@ -1368,7 +1378,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
}
|
||||
}
|
||||
if let Some((prim, offset)) = common_prim {
|
||||
let pair = scalar_pair(tag.clone(), scalar_unit(prim));
|
||||
let pair = self.scalar_pair(tag.clone(), scalar_unit(prim));
|
||||
let pair_offsets = match pair.fields {
|
||||
FieldPlacement::Arbitrary {
|
||||
ref offsets,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue