rustc: collapse Layout::FatPointer into Layout::Univariant.
This commit is contained in:
parent
3fd6b00082
commit
026214c858
|
@ -849,9 +849,6 @@ pub enum Layout {
|
||||||
/// TyArray, TySlice or TyStr.
|
/// TyArray, TySlice or TyStr.
|
||||||
Array,
|
Array,
|
||||||
|
|
||||||
/// TyRawPtr or TyRef with a !Sized pointee. The primitive is the metadata.
|
|
||||||
FatPointer,
|
|
||||||
|
|
||||||
// Remaining variants are all ADTs such as structs, enums or tuples.
|
// Remaining variants are all ADTs such as structs, enums or tuples.
|
||||||
|
|
||||||
/// Single-case enums, and structs/tuples.
|
/// Single-case enums, and structs/tuples.
|
||||||
|
@ -1132,7 +1129,7 @@ impl<'a, 'tcx> Layout {
|
||||||
memory_index: vec![0, 1]
|
memory_index: vec![0, 1]
|
||||||
};
|
};
|
||||||
Ok(tcx.intern_layout(CachedLayout {
|
Ok(tcx.intern_layout(CachedLayout {
|
||||||
layout: Layout::FatPointer,
|
layout: Layout::Univariant,
|
||||||
fields,
|
fields,
|
||||||
abi: Abi::Aggregate {
|
abi: Abi::Aggregate {
|
||||||
sized: true,
|
sized: true,
|
||||||
|
@ -1743,8 +1740,7 @@ impl<'a, 'tcx> Layout {
|
||||||
// via representation tweaks) size info beyond total size.
|
// via representation tweaks) size info beyond total size.
|
||||||
Layout::Scalar |
|
Layout::Scalar |
|
||||||
Layout::Vector |
|
Layout::Vector |
|
||||||
Layout::Array |
|
Layout::Array => {
|
||||||
Layout::FatPointer { .. } => {
|
|
||||||
debug!("print-type-size t: `{:?}` adt other", ty);
|
debug!("print-type-size t: `{:?}` adt other", ty);
|
||||||
record(adt_kind.into(), None, Vec::new())
|
record(adt_kind.into(), None, Vec::new())
|
||||||
}
|
}
|
||||||
|
@ -2047,9 +2043,23 @@ impl<'a, 'tcx> FullLayout<'tcx> {
|
||||||
fn field_type_unnormalized(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, i: usize) -> Ty<'tcx> {
|
fn field_type_unnormalized(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, i: usize) -> Ty<'tcx> {
|
||||||
let ptr_field_type = |pointee: Ty<'tcx>| {
|
let ptr_field_type = |pointee: Ty<'tcx>| {
|
||||||
assert!(i < 2);
|
assert!(i < 2);
|
||||||
|
let mk_ptr = |ty: Ty<'tcx>| {
|
||||||
|
match self.ty.sty {
|
||||||
|
ty::TyRef(r, ty::TypeAndMut { mutbl, .. }) => {
|
||||||
|
tcx.mk_ref(r, ty::TypeAndMut { ty, mutbl })
|
||||||
|
}
|
||||||
|
ty::TyRawPtr(ty::TypeAndMut { mutbl, .. }) => {
|
||||||
|
tcx.mk_ptr(ty::TypeAndMut { ty, mutbl })
|
||||||
|
}
|
||||||
|
ty::TyAdt(def, _) if def.is_box() => {
|
||||||
|
tcx.mk_box(ty)
|
||||||
|
}
|
||||||
|
_ => bug!()
|
||||||
|
}
|
||||||
|
};
|
||||||
let slice = |element: Ty<'tcx>| {
|
let slice = |element: Ty<'tcx>| {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
tcx.mk_mut_ptr(element)
|
mk_ptr(element)
|
||||||
} else {
|
} else {
|
||||||
tcx.types.usize
|
tcx.types.usize
|
||||||
}
|
}
|
||||||
|
@ -2057,7 +2067,13 @@ impl<'a, 'tcx> FullLayout<'tcx> {
|
||||||
match tcx.struct_tail(pointee).sty {
|
match tcx.struct_tail(pointee).sty {
|
||||||
ty::TySlice(element) => slice(element),
|
ty::TySlice(element) => slice(element),
|
||||||
ty::TyStr => slice(tcx.types.u8),
|
ty::TyStr => slice(tcx.types.u8),
|
||||||
ty::TyDynamic(..) => Pointer.to_ty(tcx),
|
ty::TyDynamic(..) => {
|
||||||
|
if i == 0 {
|
||||||
|
mk_ptr(tcx.mk_nil())
|
||||||
|
} else {
|
||||||
|
Pointer.to_ty(tcx)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => bug!("FullLayout::field_type({:?}): not applicable", self)
|
_ => bug!("FullLayout::field_type({:?}): not applicable", self)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2187,9 +2203,16 @@ impl<'a, 'tcx> FullLayout<'tcx> {
|
||||||
{
|
{
|
||||||
let tcx = cx.tcx();
|
let tcx = cx.tcx();
|
||||||
match (self.layout, self.abi, &self.ty.sty) {
|
match (self.layout, self.abi, &self.ty.sty) {
|
||||||
(&Layout::Scalar, Abi::Scalar(Pointer), _) if !self.ty.is_unsafe_ptr() => {
|
// FIXME(eddyb) check this via value ranges on scalars.
|
||||||
|
(&Layout::Scalar, Abi::Scalar(Pointer), &ty::TyRef(..)) |
|
||||||
|
(&Layout::Scalar, Abi::Scalar(Pointer), &ty::TyFnPtr(..)) => {
|
||||||
Ok(Some((Size::from_bytes(0), Pointer)))
|
Ok(Some((Size::from_bytes(0), Pointer)))
|
||||||
}
|
}
|
||||||
|
(&Layout::Scalar, Abi::Scalar(Pointer), &ty::TyAdt(def, _)) if def.is_box() => {
|
||||||
|
Ok(Some((Size::from_bytes(0), Pointer)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME(eddyb) check this via value ranges on scalars.
|
||||||
(&Layout::General { discr, .. }, _, &ty::TyAdt(def, _)) => {
|
(&Layout::General { discr, .. }, _, &ty::TyAdt(def, _)) => {
|
||||||
if def.discriminants(tcx).all(|d| d.to_u128_unchecked() != 0) {
|
if def.discriminants(tcx).all(|d| d.to_u128_unchecked() != 0) {
|
||||||
Ok(Some((self.fields.offset(0), discr)))
|
Ok(Some((self.fields.offset(0), discr)))
|
||||||
|
@ -2198,28 +2221,28 @@ impl<'a, 'tcx> FullLayout<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(&Layout::FatPointer, _, _) if !self.ty.is_unsafe_ptr() => {
|
|
||||||
Ok(Some((self.fields.offset(FAT_PTR_ADDR), Pointer)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is this the NonZero lang item wrapping a pointer or integer type?
|
// Is this the NonZero lang item wrapping a pointer or integer type?
|
||||||
(_, _, &ty::TyAdt(def, _)) if Some(def.did) == tcx.lang_items().non_zero() => {
|
(_, _, &ty::TyAdt(def, _)) if Some(def.did) == tcx.lang_items().non_zero() => {
|
||||||
let field = self.field(cx, 0)?;
|
let field = self.field(cx, 0)?;
|
||||||
match (field.layout, field.abi) {
|
let offset = self.fields.offset(0);
|
||||||
(&Layout::Scalar, Abi::Scalar(value)) => {
|
if let Abi::Scalar(value) = field.abi {
|
||||||
Ok(Some((self.fields.offset(0), value)))
|
Ok(Some((offset, value)))
|
||||||
}
|
} else if let ty::TyRawPtr(_) = field.ty.sty {
|
||||||
(&Layout::FatPointer, _) => {
|
// If `NonZero` contains a non-scalar `*T`, it's
|
||||||
Ok(Some((self.fields.offset(0) +
|
// a fat pointer, which starts with a thin pointer.
|
||||||
field.fields.offset(FAT_PTR_ADDR),
|
Ok(Some((offset, Pointer)))
|
||||||
Pointer)))
|
} else {
|
||||||
}
|
Ok(None)
|
||||||
_ => Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perhaps one of the fields is non-zero, let's recurse and find out.
|
// Perhaps one of the fields is non-zero, let's recurse and find out.
|
||||||
(&Layout::Univariant, _, _) => {
|
_ => {
|
||||||
|
if let FieldPlacement::Array { count, .. } = *self.fields {
|
||||||
|
if count > 0 {
|
||||||
|
return self.field(cx, 0)?.non_zero_field(cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
for i in 0..self.fields.count() {
|
for i in 0..self.fields.count() {
|
||||||
let r = self.field(cx, i)?.non_zero_field(cx)?;
|
let r = self.field(cx, i)?.non_zero_field(cx)?;
|
||||||
if let Some((offset, primitive)) = r {
|
if let Some((offset, primitive)) = r {
|
||||||
|
@ -2228,23 +2251,6 @@ impl<'a, 'tcx> FullLayout<'tcx> {
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this a fixed-size array of something non-zero
|
|
||||||
// with at least one element?
|
|
||||||
(_, _, &ty::TyArray(ety, _)) => {
|
|
||||||
if self.fields.count() != 0 {
|
|
||||||
cx.layout_of(ety)?.non_zero_field(cx)
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(_, _, &ty::TyProjection(_)) | (_, _, &ty::TyAnon(..)) => {
|
|
||||||
bug!("FullLayout::non_zero_field: {:#?} not normalized", self);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Anything else is not a non-zero type.
|
|
||||||
_ => Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2260,7 +2266,6 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Layout {
|
||||||
Scalar => {}
|
Scalar => {}
|
||||||
Vector => {}
|
Vector => {}
|
||||||
Array => {}
|
Array => {}
|
||||||
FatPointer => {}
|
|
||||||
Univariant => {}
|
Univariant => {}
|
||||||
UntaggedUnion => {}
|
UntaggedUnion => {}
|
||||||
General {
|
General {
|
||||||
|
|
Loading…
Reference in New Issue