@@ -6,9 +6,18 @@ 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
+ let mut fields = def. variants ( ) . iter ( ) . filter_map ( |v| non_zst_inner_ty ( cx, v) ) ;
12
+ if fields. clone ( ) . count ( ) != 1 {
13
+ return false ;
14
+ }
15
+ if let Some ( field) = fields. next_back ( ) {
16
+ from_ty = field. ty ( cx. tcx , args) ;
17
+ }
18
+ }
10
19
match ( & from_ty. kind ( ) , & to_ty. kind ( ) ) {
11
- ( ty:: Float ( _) | ty:: Char , ty:: Ref ( ..) | ty:: RawPtr ( _, _) ) => {
20
+ ( ty:: Uint ( _ ) | ty :: Int ( _ ) | ty :: Float ( _) | ty:: Char , ty:: Ref ( ..) | ty:: RawPtr ( _, _) ) => {
12
21
span_lint (
13
22
cx,
14
23
WRONG_TRANSMUTE ,
@@ -20,3 +29,15 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty
20
29
_ => false ,
21
30
}
22
31
}
32
+
33
+ fn non_zst_inner_ty < ' a > ( cx : & LateContext < ' _ > , variant : & ' a ty:: VariantDef ) -> Option < & ' a ty:: FieldDef > {
34
+ let tcx = cx. tcx ;
35
+ let param_env = tcx. param_env ( variant. def_id ) ;
36
+ variant. fields . iter ( ) . find ( |field| {
37
+ let field_ty = tcx. type_of ( field. did ) . instantiate_identity ( ) ;
38
+ let is_1zst = tcx
39
+ . layout_of ( param_env. and ( field_ty) )
40
+ . is_ok_and ( |layout| layout. is_1zst ( ) ) ;
41
+ !is_1zst
42
+ } )
43
+ }
0 commit comments