about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2023-05-29 14:54:48 +0200
committerLukas Markeffsky <@>2023-05-29 14:54:48 +0200
commit381b778d27e74e4fc8cc161af5a45d7bee572f47 (patch)
treefaddb9bb92bafeb27ffac4dd761d36c85e967042 /compiler
parent70e04bd88d85cab8ed110ace5a278fab106d0ef5 (diff)
Make struct layout not depend on unsizeable tail
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_abi/src/layout.rs8
1 files changed, 6 insertions, 2 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index f11c1c77f9c..6f22345617d 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -828,6 +828,7 @@ fn univariant(
     if optimize && fields.len() > 1 {
         let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() };
         let optimizing = &mut inverse_memory_index.raw[..end];
+        let fields_excluding_tail = &fields.raw[..end];
 
         // If `-Z randomize-layout` was enabled for the type definition we can shuffle
         // the field ordering to try and catch some code making assumptions about layouts
@@ -844,8 +845,11 @@ fn univariant(
             }
             // Otherwise we just leave things alone and actually optimize the type's fields
         } else {
-            let max_field_align = fields.iter().map(|f| f.align().abi.bytes()).max().unwrap_or(1);
-            let largest_niche_size = fields
+            // To allow unsizing `&Foo<Type>` -> `&Foo<dyn Trait>`, the layout of the struct must
+            // not depend on the layout of the tail.
+            let max_field_align =
+                fields_excluding_tail.iter().map(|f| f.align().abi.bytes()).max().unwrap_or(1);
+            let largest_niche_size = fields_excluding_tail
                 .iter()
                 .filter_map(|f| f.largest_niche())
                 .map(|n| n.available(dl))