Skip to content

Commit 478071b

Browse files
author
Lukas Markeffsky
committed
clean up struct layout code
1 parent 4b6749b commit 478071b

File tree

2 files changed

+41
-36
lines changed

2 files changed

+41
-36
lines changed

compiler/rustc_abi/src/layout.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ pub trait LayoutCalculator {
134134
scalar_valid_range: (Bound<u128>, Bound<u128>),
135135
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
136136
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
137-
niche_optimize_enum: bool,
137+
dont_niche_optimize_enum: bool,
138138
always_sized: bool,
139139
) -> Option<LayoutS> {
140140
let dl = self.current_data_layout();
@@ -183,10 +183,10 @@ pub trait LayoutCalculator {
183183
// (Typechecking will reject discriminant-sizing attrs.)
184184

185185
let v = present_first;
186-
let kind = if is_enum || variants[v].is_empty() {
186+
let kind = if is_enum || variants[v].is_empty() || always_sized {
187187
StructKind::AlwaysSized
188188
} else {
189-
if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized }
189+
StructKind::MaybeUnsized
190190
};
191191

192192
let mut st = self.univariant(dl, &variants[v], repr, kind)?;
@@ -280,7 +280,7 @@ pub trait LayoutCalculator {
280280
}
281281

282282
let calculate_niche_filling_layout = || -> Option<TmpLayout> {
283-
if niche_optimize_enum {
283+
if dont_niche_optimize_enum {
284284
return None;
285285
}
286286

compiler/rustc_ty_utils/src/layout.rs

+37-32
Original file line numberDiff line numberDiff line change
@@ -463,38 +463,43 @@ fn layout_of_uncached<'tcx>(
463463
));
464464
}
465465

466-
tcx.mk_layout(
467-
cx.layout_of_struct_or_enum(
468-
&def.repr(),
469-
&variants,
470-
def.is_enum(),
471-
def.is_unsafe_cell(),
472-
tcx.layout_scalar_valid_range(def.did()),
473-
|min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max),
474-
def.is_enum()
475-
.then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))
476-
.into_iter()
477-
.flatten(),
478-
def.repr().inhibit_enum_layout_opt()
479-
|| def
480-
.variants()
481-
.iter_enumerated()
482-
.any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32())),
483-
{
484-
let param_env = tcx.param_env(def.did());
485-
def.is_struct()
486-
&& match def.variants().iter().next().and_then(|x| x.fields.raw.last())
487-
{
488-
Some(last_field) => tcx
489-
.type_of(last_field.did)
490-
.subst_identity()
491-
.is_sized(tcx, param_env),
492-
None => false,
493-
}
494-
},
495-
)
496-
.ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?,
497-
)
466+
let get_discriminant_type =
467+
|min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max);
468+
469+
let discriminants_iter = || {
470+
def.is_enum()
471+
.then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))
472+
.into_iter()
473+
.flatten()
474+
};
475+
476+
let dont_niche_optimize_enum = def.repr().inhibit_enum_layout_opt()
477+
|| def
478+
.variants()
479+
.iter_enumerated()
480+
.any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()));
481+
482+
let maybe_unsized = def.is_struct()
483+
&& def.non_enum_variant().fields.raw.last().is_some_and(|last_field| {
484+
let param_env = tcx.param_env(def.did());
485+
!tcx.type_of(last_field.did).subst_identity().is_sized(tcx, param_env)
486+
});
487+
488+
let Some(layout) = cx.layout_of_struct_or_enum(
489+
&def.repr(),
490+
&variants,
491+
def.is_enum(),
492+
def.is_unsafe_cell(),
493+
tcx.layout_scalar_valid_range(def.did()),
494+
get_discriminant_type,
495+
discriminants_iter(),
496+
dont_niche_optimize_enum,
497+
!maybe_unsized,
498+
) else {
499+
return Err(error(cx, LayoutError::SizeOverflow(ty)));
500+
};
501+
502+
tcx.mk_layout(layout)
498503
}
499504

500505
// Types with no meaningful known layout.

0 commit comments

Comments
 (0)