Skip to content

Commit e5d85f9

Browse files
allow reordering of the last field of a MaybeUnsized struct if it's a ZST
1 parent d3b9ece commit e5d85f9

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

compiler/rustc_middle/src/ty/layout.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)