@@ -2013,34 +2013,32 @@ impl CodeGenerator for CompInfo {
2013
2013
attributes. push ( attributes:: doc ( comment) ) ;
2014
2014
}
2015
2015
2016
- let explicit_align = if ctx. options ( ) . rust_features ( ) . repr_align {
2017
- explicit_align
2018
- } else {
2019
- None
2020
- } ;
2016
+ let mut needs_packed_wrapper = false ;
2021
2017
2022
2018
// We can't specify both packed(N) and align(N), but the packed()
2023
2019
// should be redundant in this case.
2024
- if packed && !is_opaque && explicit_align . is_none ( ) {
2020
+ if packed && !is_opaque {
2025
2021
let n = layout. map_or ( 1 , |l| l. align ) ;
2026
2022
assert ! ( ctx. options( ) . rust_features( ) . repr_packed_n || n == 1 ) ;
2027
- let packed_repr = if n == 1 {
2023
+ if explicit_align. is_some ( ) {
2024
+ needs_packed_wrapper = true ;
2025
+ }
2026
+ let packed_repr = if n == 1 || needs_packed_wrapper {
2028
2027
"packed" . to_string ( )
2029
2028
} else {
2030
2029
format ! ( "packed({})" , n)
2031
2030
} ;
2032
2031
attributes. push ( attributes:: repr_list ( & [ "C" , & packed_repr] ) ) ;
2033
2032
} else {
2034
2033
attributes. push ( attributes:: repr ( "C" ) ) ;
2035
- }
2036
-
2037
- if let Some ( explicit) = explicit_align {
2038
- // Ensure that the struct has the correct alignment even in
2039
- // presence of alignas.
2040
- let explicit = helpers:: ast_ty:: int_expr ( explicit as i64 ) ;
2041
- attributes. push ( quote ! {
2042
- #[ repr( align( #explicit) ) ]
2043
- } ) ;
2034
+ if let Some ( explicit) = explicit_align {
2035
+ // Ensure that the struct has the correct alignment even in
2036
+ // presence of alignas.
2037
+ let explicit = helpers:: ast_ty:: int_expr ( explicit as i64 ) ;
2038
+ attributes. push ( quote ! {
2039
+ #[ repr( align( #explicit) ) ]
2040
+ } ) ;
2041
+ }
2044
2042
}
2045
2043
2046
2044
let derivable_traits = derives_of_item ( item, ctx, packed) ;
@@ -2093,15 +2091,21 @@ impl CodeGenerator for CompInfo {
2093
2091
attributes. push ( attributes:: must_use ( ) ) ;
2094
2092
}
2095
2093
2094
+ let layout_ident = if needs_packed_wrapper {
2095
+ ctx. rust_ident ( canonical_name. to_owned ( ) + "__packed" )
2096
+ } else {
2097
+ canonical_ident. clone ( )
2098
+ } ;
2099
+
2096
2100
let mut tokens = if is_union && struct_layout. is_rust_union ( ) {
2097
2101
quote ! {
2098
2102
#( #attributes ) *
2099
- pub union #canonical_ident
2103
+ pub union #layout_ident
2100
2104
}
2101
2105
} else {
2102
2106
quote ! {
2103
2107
#( #attributes ) *
2104
- pub struct #canonical_ident
2108
+ pub struct #layout_ident
2105
2109
}
2106
2110
} ;
2107
2111
@@ -2112,6 +2116,16 @@ impl CodeGenerator for CompInfo {
2112
2116
} ) ;
2113
2117
result. push ( tokens) ;
2114
2118
2119
+ if needs_packed_wrapper {
2120
+ let attributes = attributes:: derives ( & derives) ;
2121
+ let align = proc_macro2:: TokenStream :: from_str ( & explicit_align. unwrap ( ) . to_string ( ) ) . unwrap ( ) ;
2122
+ result. push ( quote ! {
2123
+ #attributes
2124
+ #[ repr( C , align( #align) ) ]
2125
+ pub struct #canonical_ident( #layout_ident) ;
2126
+ } ) ;
2127
+ }
2128
+
2115
2129
// Generate the inner types and all that stuff.
2116
2130
//
2117
2131
// TODO: In the future we might want to be smart, and use nested
@@ -2211,12 +2225,17 @@ impl CodeGenerator for CompInfo {
2211
2225
let uninit_decl = if !check_field_offset. is_empty ( ) {
2212
2226
// FIXME: When MSRV >= 1.59.0, we can use
2213
2227
// > const PTR: *const #canonical_ident = ::#prefix::mem::MaybeUninit::uninit().as_ptr();
2228
+ let layout_cast = if needs_packed_wrapper {
2229
+ Some ( quote ! ( as * const #layout_ident) )
2230
+ } else {
2231
+ None
2232
+ } ;
2214
2233
Some ( quote ! {
2215
2234
// Use a shared MaybeUninit so that rustc with
2216
2235
// opt-level=0 doesn't take too much stack space,
2217
2236
// see #2218.
2218
2237
const UNINIT : :: #prefix:: mem:: MaybeUninit <#canonical_ident> = :: #prefix:: mem:: MaybeUninit :: uninit( ) ;
2219
- let ptr = UNINIT . as_ptr( ) ;
2238
+ let ptr = UNINIT . as_ptr( ) #layout_cast ;
2220
2239
} )
2221
2240
} else {
2222
2241
None
0 commit comments