@@ -6,9 +6,21 @@ use rustc_middle::ty::{self, Ty};
6
6
7
7
/// Checks for `wrong_transmute` lint.
8
8
/// Returns `true` if it's triggered, otherwise returns `false`.
9
- pub ( super ) fn check < ' tcx > ( cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > , from_ty : Ty < ' tcx > , to_ty : Ty < ' tcx > ) -> bool {
9
+ pub ( super ) fn check < ' tcx > ( cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > , mut from_ty : Ty < ' tcx > , to_ty : Ty < ' tcx > ) -> bool {
10
+ if let ty:: Adt ( def, args) = from_ty. kind ( ) {
11
+ if def. repr ( ) . transparent ( ) {
12
+ if let Some ( field) = def
13
+ . variants ( )
14
+ . iter ( )
15
+ . filter_map ( |v| transparent_non_zst_inner_ty ( cx, v) )
16
+ . next_back ( )
17
+ {
18
+ from_ty = field. ty ( cx. tcx , args) ;
19
+ }
20
+ }
21
+ }
10
22
match ( & from_ty. kind ( ) , & to_ty. kind ( ) ) {
11
- ( ty:: Float ( _) | ty:: Char , ty:: Ref ( ..) | ty:: RawPtr ( _, _) ) => {
23
+ ( ty:: Uint ( _ ) | ty :: Int ( _ ) | ty :: Float ( _) | ty:: Char , ty:: Ref ( ..) | ty:: RawPtr ( _, _) ) => {
12
24
span_lint (
13
25
cx,
14
26
WRONG_TRANSMUTE ,
@@ -20,3 +32,15 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty
20
32
_ => false ,
21
33
}
22
34
}
35
+
36
+ fn transparent_non_zst_inner_ty < ' a > ( cx : & LateContext < ' _ > , variant : & ' a ty:: VariantDef ) -> Option < & ' a ty:: FieldDef > {
37
+ let tcx = cx. tcx ;
38
+ let param_env = tcx. param_env ( variant. def_id ) ;
39
+ variant. fields . iter ( ) . find ( |field| {
40
+ let field_ty = tcx. type_of ( field. did ) . instantiate_identity ( ) ;
41
+ let is_1zst = tcx
42
+ . layout_of ( param_env. and ( field_ty) )
43
+ . is_ok_and ( |layout| layout. is_1zst ( ) ) ;
44
+ !is_1zst
45
+ } )
46
+ }
0 commit comments