@@ -999,7 +999,7 @@ where
999999 }
10001000
10011001 _ => {
1002- let mut data_variant = match this. variants {
1002+ let ( mut data_variant, align ) = match this. variants {
10031003 // Within the discriminant field, only the niche itself is
10041004 // always initialized, so we only check for a pointer at its
10051005 // offset.
@@ -1012,13 +1012,24 @@ where
10121012 // using more niches than just null (e.g., the first page of
10131013 // the address space, or unaligned pointers).
10141014 Variants :: Multiple {
1015- tag_encoding : TagEncoding :: Niche { untagged_variant, .. } ,
1015+ tag_encoding :
1016+ TagEncoding :: Niche { untagged_variant, ref niche_variants, .. } ,
10161017 tag_field,
10171018 ..
10181019 } if this. fields . offset ( tag_field) == offset => {
1019- Some ( this. for_variant ( cx, untagged_variant) )
1020+ // When a non-zero niche exists, we cannot safely keep
1021+ // the alignment of the pointer. These niches typically
1022+ // don't meet the alignment requirements of the pointer.
1023+ let align = if niche_variants. start ( ) . as_u32 ( ) != 0
1024+ || niche_variants. end ( ) . as_u32 ( ) != 0
1025+ {
1026+ Some ( Align :: ONE )
1027+ } else {
1028+ None
1029+ } ;
1030+ ( Some ( this. for_variant ( cx, untagged_variant) ) , align)
10201031 }
1021- _ => Some ( this) ,
1032+ _ => ( Some ( this) , None ) ,
10221033 } ;
10231034
10241035 if let Some ( variant) = data_variant {
@@ -1055,20 +1066,23 @@ where
10551066 }
10561067 }
10571068
1058- // Fixup info for the first field of a `Box`. Recursive traversal will have found
1059- // the raw pointer, so size and align are set to the boxed type, but `pointee.safe`
1060- // will still be `None`.
10611069 if let Some ( ref mut pointee) = result {
10621070 if offset. bytes ( ) == 0
10631071 && let Some ( boxed_ty) = this. ty . boxed_ty ( )
10641072 {
1073+ // Fixup info for the first field of a `Box`. Recursive traversal will have found
1074+ // the raw pointer, so size and align are set to the boxed type, but `pointee.safe`
1075+ // will still be `None`.
10651076 debug_assert ! ( pointee. safe. is_none( ) ) ;
10661077 let optimize = tcx. sess . opts . optimize != OptLevel :: No ;
10671078 pointee. safe = Some ( PointerKind :: Box {
10681079 unpin : optimize && boxed_ty. is_unpin ( tcx, cx. param_env ( ) ) ,
10691080 global : this. ty . is_box_global ( tcx) ,
10701081 } ) ;
10711082 }
1083+ if let Some ( align) = align {
1084+ pointee. align = align;
1085+ }
10721086 }
10731087
10741088 result
0 commit comments