@@ -289,25 +289,32 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
289289
290290 let optimize = !repr. inhibit_struct_field_reordering_opt ( ) ;
291291 if optimize {
292- let end =
293- if let StructKind :: MaybeUnsized = kind { fields. len ( ) - 1 } else { fields. len ( ) } ;
294- let optimizing = & mut inverse_memory_index[ ..end] ;
295292 let field_align = |f : & TyAndLayout < ' _ > | {
296293 if let Some ( pack) = pack { f. align . abi . min ( pack) } else { f. align . abi }
297294 } ;
298295 match kind {
299- StructKind :: AlwaysSized | StructKind :: MaybeUnsized => {
300- optimizing . sort_by_key ( |& x| {
296+ StructKind :: AlwaysSized => {
297+ inverse_memory_index . sort_by_key ( |& x| {
301298 // Place ZSTs first to avoid "interesting offsets",
302299 // especially with only one or two non-ZST fields.
303300 let f = & fields[ x as usize ] ;
304301 ( !f. is_zst ( ) , cmp:: Reverse ( field_align ( f) ) )
305302 } ) ;
306303 }
304+ StructKind :: MaybeUnsized => {
305+ // Sort in descending alignment, except for the last field,
306+ // which may be accessed through an unsized type.
307+ inverse_memory_index[ ..fields. len ( ) - 1 ]
308+ . sort_by_key ( |& x| cmp:: Reverse ( field_align ( & fields[ x as usize ] ) ) ) ;
309+ // Place ZSTs first to avoid "interesting offsets".
310+ // This will reorder the last field if it is a ZST, which is okay because
311+ // there's nothing in memory that could be accessed through an unsized type.
312+ inverse_memory_index. sort_by_key ( |& x| !fields[ x as usize ] . is_zst ( ) ) ;
313+ }
307314 StructKind :: Prefixed ( ..) => {
308315 // Sort in ascending alignment so that the layout stay optimal
309316 // regardless of the prefix
310- optimizing . sort_by_key ( |& x| field_align ( & fields[ x as usize ] ) ) ;
317+ inverse_memory_index . sort_by_key ( |& x| field_align ( & fields[ x as usize ] ) ) ;
311318 }
312319 }
313320 }
0 commit comments