mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
clean up struct layout code
This commit is contained in:
parent
4b6749b21e
commit
478071ba9d
@ -134,7 +134,7 @@ pub trait LayoutCalculator {
|
|||||||
scalar_valid_range: (Bound<u128>, Bound<u128>),
|
scalar_valid_range: (Bound<u128>, Bound<u128>),
|
||||||
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
|
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
|
||||||
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
||||||
niche_optimize_enum: bool,
|
dont_niche_optimize_enum: bool,
|
||||||
always_sized: bool,
|
always_sized: bool,
|
||||||
) -> Option<LayoutS> {
|
) -> Option<LayoutS> {
|
||||||
let dl = self.current_data_layout();
|
let dl = self.current_data_layout();
|
||||||
@ -183,10 +183,10 @@ pub trait LayoutCalculator {
|
|||||||
// (Typechecking will reject discriminant-sizing attrs.)
|
// (Typechecking will reject discriminant-sizing attrs.)
|
||||||
|
|
||||||
let v = present_first;
|
let v = present_first;
|
||||||
let kind = if is_enum || variants[v].is_empty() {
|
let kind = if is_enum || variants[v].is_empty() || always_sized {
|
||||||
StructKind::AlwaysSized
|
StructKind::AlwaysSized
|
||||||
} else {
|
} else {
|
||||||
if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
|
StructKind::MaybeUnsized
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut st = self.univariant(dl, &variants[v], repr, kind)?;
|
let mut st = self.univariant(dl, &variants[v], repr, kind)?;
|
||||||
@ -280,7 +280,7 @@ pub trait LayoutCalculator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let calculate_niche_filling_layout = || -> Option<TmpLayout> {
|
let calculate_niche_filling_layout = || -> Option<TmpLayout> {
|
||||||
if niche_optimize_enum {
|
if dont_niche_optimize_enum {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,38 +463,43 @@ fn layout_of_uncached<'tcx>(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
tcx.mk_layout(
|
let get_discriminant_type =
|
||||||
cx.layout_of_struct_or_enum(
|
|min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max);
|
||||||
&def.repr(),
|
|
||||||
&variants,
|
let discriminants_iter = || {
|
||||||
def.is_enum(),
|
def.is_enum()
|
||||||
def.is_unsafe_cell(),
|
.then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))
|
||||||
tcx.layout_scalar_valid_range(def.did()),
|
.into_iter()
|
||||||
|min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max),
|
.flatten()
|
||||||
def.is_enum()
|
};
|
||||||
.then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))
|
|
||||||
.into_iter()
|
let dont_niche_optimize_enum = def.repr().inhibit_enum_layout_opt()
|
||||||
.flatten(),
|
|| def
|
||||||
def.repr().inhibit_enum_layout_opt()
|
.variants()
|
||||||
|| def
|
.iter_enumerated()
|
||||||
.variants()
|
.any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()));
|
||||||
.iter_enumerated()
|
|
||||||
.any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32())),
|
let maybe_unsized = def.is_struct()
|
||||||
{
|
&& def.non_enum_variant().fields.raw.last().is_some_and(|last_field| {
|
||||||
let param_env = tcx.param_env(def.did());
|
let param_env = tcx.param_env(def.did());
|
||||||
def.is_struct()
|
!tcx.type_of(last_field.did).subst_identity().is_sized(tcx, param_env)
|
||||||
&& match def.variants().iter().next().and_then(|x| x.fields.raw.last())
|
});
|
||||||
{
|
|
||||||
Some(last_field) => tcx
|
let Some(layout) = cx.layout_of_struct_or_enum(
|
||||||
.type_of(last_field.did)
|
&def.repr(),
|
||||||
.subst_identity()
|
&variants,
|
||||||
.is_sized(tcx, param_env),
|
def.is_enum(),
|
||||||
None => false,
|
def.is_unsafe_cell(),
|
||||||
}
|
tcx.layout_scalar_valid_range(def.did()),
|
||||||
},
|
get_discriminant_type,
|
||||||
)
|
discriminants_iter(),
|
||||||
.ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?,
|
dont_niche_optimize_enum,
|
||||||
)
|
!maybe_unsized,
|
||||||
|
) else {
|
||||||
|
return Err(error(cx, LayoutError::SizeOverflow(ty)));
|
||||||
|
};
|
||||||
|
|
||||||
|
tcx.mk_layout(layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types with no meaningful known layout.
|
// Types with no meaningful known layout.
|
||||||
|
Loading…
Reference in New Issue
Block a user