about summary refs log tree commit diff
path: root/compiler/rustc_ty_utils/src
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2023-07-02 14:06:56 +0200
committerLukas Markeffsky <@>2023-07-06 13:04:13 +0000
commit478071ba9daabcdbc880db5638989dc16545537c (patch)
treee48e202d7b7f58b86f189bfc515216f6be8e6173 /compiler/rustc_ty_utils/src
parent4b6749b21e680a6280cf05ace533ae20c93d9bff (diff)
downloadrust-478071ba9daabcdbc880db5638989dc16545537c.tar.gz
rust-478071ba9daabcdbc880db5638989dc16545537c.zip
clean up struct layout code
Diffstat (limited to 'compiler/rustc_ty_utils/src')
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs69
1 files changed, 37 insertions, 32 deletions
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 9ef9120e294..f6bc0dc330d 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -463,38 +463,43 @@ fn layout_of_uncached<'tcx>(
                 ));
             }
 
-            tcx.mk_layout(
-                cx.layout_of_struct_or_enum(
-                    &def.repr(),
-                    &variants,
-                    def.is_enum(),
-                    def.is_unsafe_cell(),
-                    tcx.layout_scalar_valid_range(def.did()),
-                    |min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max),
-                    def.is_enum()
-                        .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))
-                        .into_iter()
-                        .flatten(),
-                    def.repr().inhibit_enum_layout_opt()
-                        || def
-                            .variants()
-                            .iter_enumerated()
-                            .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32())),
-                    {
-                        let param_env = tcx.param_env(def.did());
-                        def.is_struct()
-                            && match def.variants().iter().next().and_then(|x| x.fields.raw.last())
-                            {
-                                Some(last_field) => tcx
-                                    .type_of(last_field.did)
-                                    .subst_identity()
-                                    .is_sized(tcx, param_env),
-                                None => false,
-                            }
-                    },
-                )
-                .ok_or_else(|| error(cx, LayoutError::SizeOverflow(ty)))?,
-            )
+            let get_discriminant_type =
+                |min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max);
+
+            let discriminants_iter = || {
+                def.is_enum()
+                    .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128)))
+                    .into_iter()
+                    .flatten()
+            };
+
+            let dont_niche_optimize_enum = def.repr().inhibit_enum_layout_opt()
+                || def
+                    .variants()
+                    .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());
+                    !tcx.type_of(last_field.did).subst_identity().is_sized(tcx, param_env)
+                });
+
+            let Some(layout) = cx.layout_of_struct_or_enum(
+                &def.repr(),
+                &variants,
+                def.is_enum(),
+                def.is_unsafe_cell(),
+                tcx.layout_scalar_valid_range(def.did()),
+                get_discriminant_type,
+                discriminants_iter(),
+                dont_niche_optimize_enum,
+                !maybe_unsized,
+            ) else {
+                return Err(error(cx, LayoutError::SizeOverflow(ty)));
+            };
+
+            tcx.mk_layout(layout)
         }
 
         // Types with no meaningful known layout.