@@ -289,25 +289,32 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
289
289
290
290
let optimize = !repr. inhibit_struct_field_reordering_opt ( ) ;
291
291
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] ;
295
292
let field_align = |f : & TyAndLayout < ' _ > | {
296
293
if let Some ( pack) = pack { f. align . abi . min ( pack) } else { f. align . abi }
297
294
} ;
298
295
match kind {
299
- StructKind :: AlwaysSized | StructKind :: MaybeUnsized => {
300
- optimizing . sort_by_key ( |& x| {
296
+ StructKind :: AlwaysSized => {
297
+ inverse_memory_index . sort_by_key ( |& x| {
301
298
// Place ZSTs first to avoid "interesting offsets",
302
299
// especially with only one or two non-ZST fields.
303
300
let f = & fields[ x as usize ] ;
304
301
( !f. is_zst ( ) , cmp:: Reverse ( field_align ( f) ) )
305
302
} ) ;
306
303
}
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
+ }
307
314
StructKind :: Prefixed ( ..) => {
308
315
// Sort in ascending alignment so that the layout stay optimal
309
316
// 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 ] ) ) ;
311
318
}
312
319
}
313
320
}
0 commit comments