@@ -2047,6 +2047,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
20472047
20482048 let bitfield_ty_item = ctx. resolve_item ( self . ty ( ) ) ;
20492049 let bitfield_ty = bitfield_ty_item. expect_type ( ) ;
2050+ let bitfield_ty_kind = bitfield_ty. canonical_type ( ctx) . kind ( ) ;
20502051 let bitfield_ty_ident = bitfield_ty. name ( ) ;
20512052
20522053 let bitfield_ty_layout = bitfield_ty
@@ -2132,36 +2133,61 @@ impl<'a> FieldCodegen<'a> for Bitfield {
21322133 }
21332134 } ) ) ;
21342135 } else {
2136+ let is_rust_union =
2137+ parent. is_union ( ) && struct_layout. is_rust_union ( ) ;
2138+
2139+ let get = quote ! { self . #unit_field_ident. get_const:: <#offset, #width>( ) as #bitfield_int_ty } ;
2140+ let raw_get = quote ! {
2141+ <#unit_field_ty>:: raw_get_const:: <#offset, #width>(
2142+ :: #prefix:: ptr:: addr_of!( ( * this) . #unit_field_ident) ,
2143+ ) as #bitfield_int_ty
2144+ } ;
2145+
2146+ let ( getter_inner, raw_getter_inner) = match bitfield_ty_kind {
2147+ TypeKind :: Int ( IntKind :: Bool ) => {
2148+ ( quote ! { #get != 0 } , quote ! { #raw_get != 0 } )
2149+ }
2150+ TypeKind :: Enum ( ..) => (
2151+ quote ! { :: #prefix:: mem:: transmute( #get) } ,
2152+ quote ! { :: #prefix:: mem:: transmute( #raw_get) } ,
2153+ ) ,
2154+ _ => ( quote ! { #get as _ } , quote ! { #raw_get as _ } ) ,
2155+ } ;
2156+
2157+ let getter_body = if is_rust_union ||
2158+ matches ! ( bitfield_ty_kind, TypeKind :: Enum ( ..) )
2159+ {
2160+ quote ! { unsafe { #getter_inner } }
2161+ } else {
2162+ getter_inner
2163+ } ;
2164+
2165+ let setter_inner = quote ! {
2166+ let val: #bitfield_int_ty = val as _;
2167+ self . #unit_field_ident. set_const:: <#offset, #width>( val as u64 )
2168+ } ;
2169+ let setter_body = if is_rust_union {
2170+ quote ! { unsafe { #setter_inner } }
2171+ } else {
2172+ setter_inner
2173+ } ;
2174+
21352175 methods. extend ( Some ( quote ! {
21362176 #[ inline]
21372177 #access_spec fn #getter_name( & self ) -> #bitfield_ty {
2138- unsafe {
2139- :: #prefix:: mem:: transmute(
2140- self . #unit_field_ident. get_const:: <#offset, #width>( )
2141- as #bitfield_int_ty
2142- )
2143- }
2178+ #getter_body
21442179 }
21452180
21462181 #[ inline]
21472182 #access_spec fn #setter_name( & mut self , val: #bitfield_ty) {
2148- unsafe {
2149- let val: #bitfield_int_ty = val as _;
2150- self . #unit_field_ident. set_const:: <#offset, #width>(
2151- val as u64
2152- )
2153- }
2183+ #setter_body
21542184 }
21552185 } ) ) ;
21562186
21572187 methods. extend ( Some ( quote ! {
21582188 #[ inline]
21592189 #access_spec unsafe fn #raw_getter_name( this: * const Self ) -> #bitfield_ty {
2160- unsafe {
2161- :: #prefix:: mem:: transmute( <#unit_field_ty>:: raw_get_const:: <#offset, #width>(
2162- :: #prefix:: ptr:: addr_of!( ( * this) . #unit_field_ident) ,
2163- ) as #bitfield_int_ty)
2164- }
2190+ unsafe { #raw_getter_inner }
21652191 }
21662192
21672193 #[ inline]
0 commit comments