@@ -100,19 +100,18 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
100100
101101 // # First compute the dynamic alignment
102102
103- // Packed type alignment would have to be capped, but their tails always have known alignment.
104- // Therefore, their alignment has already been taken into account when computing `sized_align`
105- // and `unsized_offset_unadjusted`, so no further adjustment is needed.
106- if let ty:: Adt ( def, _) = t. kind ( ) {
107- if def. repr ( ) . packed ( ) {
108- let unsized_tail =
109- bx. tcx ( ) . struct_tail_with_normalize ( field_ty, |ty| ty, || { } ) ;
110- assert ! ( matches!( unsized_tail. kind( ) , ty:: Slice ( ..) | ty:: Str ) ) ;
111- // Therefore we do not need to adjust anything.
112- // It's not actually correct to say that the unsized field has this alignment, but the
113- // code below works correctly if we set this and it avoids having to compute
114- // the actual alignment (which is `unsized_align.min(packed)`).
115- unsized_align = sized_align;
103+ // For packed types, we need to cap the alignment.
104+ if let ty:: Adt ( def, _) = t. kind ( )
105+ && let Some ( packed) = def. repr ( ) . pack
106+ {
107+ if packed. bytes ( ) == 1 {
108+ // We know this will be capped to 1.
109+ unsized_align = bx. const_usize ( 1 ) ;
110+ } else {
111+ // We have to dynamically compute `min(unsized_align, packed)`.
112+ let packed = bx. const_usize ( packed. bytes ( ) ) ;
113+ let cmp = bx. icmp ( IntPredicate :: IntULT , unsized_align, packed) ;
114+ unsized_align = bx. select ( cmp, unsized_align, packed) ;
116115 }
117116 }
118117
@@ -143,8 +142,6 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
143142 // let full_size = (offset + unsized_size).align_to(unsized_align).align_to(full_align);
144143 // Furthermore, `align >= unsized_align`, and therefore we only need to do:
145144 // let full_size = (offset + unsized_size).align_to(full_align);
146- // This formula also has the advantage of working correctly when the type is packed
147- // and we set `unsized_align = sized_align`.
148145
149146 let full_size = bx. add ( unsized_offset_unadjusted, unsized_size) ;
150147
0 commit comments