about summary refs log tree commit diff
path: root/compiler/rustc_abi/src/layout.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_abi/src/layout.rs')
-rw-r--r--compiler/rustc_abi/src/layout.rs40
1 files changed, 18 insertions, 22 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 75c64aabfbb..aea88641f82 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -40,7 +40,7 @@ pub trait LayoutCalculator {
             largest_niche,
             align,
             size,
-            repr_align: None,
+            max_repr_align: None,
             unadjusted_abi_align: align.abi,
         }
     }
@@ -124,7 +124,7 @@ pub trait LayoutCalculator {
             largest_niche: None,
             align: dl.i8_align,
             size: Size::ZERO,
-            repr_align: None,
+            max_repr_align: None,
             unadjusted_abi_align: dl.i8_align.abi,
         }
     }
@@ -293,6 +293,7 @@ pub trait LayoutCalculator {
             }
 
             let mut align = dl.aggregate_align;
+            let mut max_repr_align = repr.align;
             let mut unadjusted_abi_align = align.abi;
 
             let mut variant_layouts = variants
@@ -302,6 +303,7 @@ pub trait LayoutCalculator {
                     st.variants = Variants::Single { index: j };
 
                     align = align.max(st.align);
+                    max_repr_align = max_repr_align.max(st.max_repr_align);
                     unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align);
 
                     Some(st)
@@ -429,7 +431,7 @@ pub trait LayoutCalculator {
                 largest_niche,
                 size,
                 align,
-                repr_align: repr.align,
+                max_repr_align,
                 unadjusted_abi_align,
             };
 
@@ -465,6 +467,7 @@ pub trait LayoutCalculator {
         let (min_ity, signed) = discr_range_of_repr(min, max); //Integer::repr_discr(tcx, ty, &repr, min, max);
 
         let mut align = dl.aggregate_align;
+        let mut max_repr_align = repr.align;
         let mut unadjusted_abi_align = align.abi;
 
         let mut size = Size::ZERO;
@@ -509,6 +512,7 @@ pub trait LayoutCalculator {
                 }
                 size = cmp::max(size, st.size);
                 align = align.max(st.align);
+                max_repr_align = max_repr_align.max(st.max_repr_align);
                 unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align);
                 Some(st)
             })
@@ -703,7 +707,7 @@ pub trait LayoutCalculator {
             abi,
             align,
             size,
-            repr_align: repr.align,
+            max_repr_align,
             unadjusted_abi_align,
         };
 
@@ -744,6 +748,7 @@ pub trait LayoutCalculator {
         let dl = self.current_data_layout();
         let dl = dl.borrow();
         let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
+        let mut max_repr_align = repr.align;
 
         // If all the non-ZST fields have the same ABI and union ABI optimizations aren't
         // disabled, we can use that common ABI for the union as a whole.
@@ -761,6 +766,7 @@ pub trait LayoutCalculator {
             assert!(field.0.is_sized());
 
             align = align.max(field.align());
+            max_repr_align = max_repr_align.max(field.max_repr_align());
             size = cmp::max(size, field.size());
 
             if field.0.is_zst() {
@@ -827,7 +833,7 @@ pub trait LayoutCalculator {
             largest_niche: None,
             align,
             size: size.align_to(align.abi),
-            repr_align: repr.align,
+            max_repr_align,
             unadjusted_abi_align,
         })
     }
@@ -849,6 +855,7 @@ fn univariant(
 ) -> Option<LayoutS> {
     let pack = repr.pack;
     let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
+    let mut max_repr_align = repr.align;
     let mut inverse_memory_index: IndexVec<u32, FieldIdx> = fields.indices().collect();
     let optimize = !repr.inhibit_struct_field_reordering_opt();
     if optimize && fields.len() > 1 {
@@ -1017,6 +1024,7 @@ fn univariant(
         };
         offset = offset.align_to(field_align.abi);
         align = align.max(field_align);
+        max_repr_align = max_repr_align.max(field.max_repr_align());
 
         debug!("univariant offset: {:?} field: {:#?}", offset, field);
         offsets[i] = offset;
@@ -1133,28 +1141,16 @@ fn univariant(
         abi = Abi::Uninhabited;
     }
 
-    let (repr_align, unadjusted_abi_align) = if repr.transparent() {
+    let unadjusted_abi_align = if repr.transparent() {
         match layout_of_single_non_zst_field {
-            Some(l) => (l.repr_align(), l.unadjusted_abi_align()),
+            Some(l) => l.unadjusted_abi_align(),
             None => {
                 // `repr(transparent)` with all ZST fields.
-                //
-                // Using `None` for `repr_align` here is technically incorrect, since one of
-                // the ZSTs could have `repr(align(1))`. It's an interesting question, if you have
-                // `#{repr(transparent)] struct Foo((), ZstWithReprAlign1)`, which of those ZSTs'
-                // ABIs is forwarded by `repr(transparent)`? The answer to that question determines
-                // whether we should use `None` or `Some(align 1)` here. Thanksfully, two things
-                // together mean this doesn't matter:
-                // - You're not allowed to have a `repr(transparent)` struct that contains
-                //   `repr(align)` > 1 ZSTs. See error E0691.
-                // - MSVC never treats requested align 1 differently from natural align 1.
-                //   (And the `repr_align` field is only used on i686-windows, see `LayoutS` docs.)
-                // So just use `None` for now.
-                (None, align.abi)
+                align.abi
             }
         }
     } else {
-        (repr.align, unadjusted_abi_align)
+        unadjusted_abi_align
     };
 
     Some(LayoutS {
@@ -1164,7 +1160,7 @@ fn univariant(
         largest_niche,
         align,
         size,
-        repr_align,
+        max_repr_align,
         unadjusted_abi_align,
     })
 }