@@ -5,31 +5,59 @@ use rustc_lint::LateContext;
55use rustc_middle:: ty:: { self , GenericArgKind , Ty } ;
66
77pub ( super ) fn check < ' tcx > ( cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > , from_ty : Ty < ' tcx > , to_ty : Ty < ' tcx > ) -> bool {
8- from_ty
9- . walk ( )
10- . zip ( to_ty. walk ( ) )
11- . filter_map ( |( from_ty, to_ty) | {
12- if let ( GenericArgKind :: Type ( from_ty) , GenericArgKind :: Type ( to_ty) ) = ( from_ty. kind ( ) , to_ty. kind ( ) ) {
13- Some ( ( from_ty, to_ty) )
14- } else {
15- None
8+ // assumes walk will return all types in the same order
9+ let mut from_ty_walker = from_ty. walk ( ) ;
10+ let mut to_ty_walker = to_ty. walk ( ) ;
11+ let mut found = false ;
12+ while let Some ( ( from_ty, to_ty) ) = from_ty_walker. next ( ) . zip ( to_ty_walker. next ( ) ) {
13+ if let ( GenericArgKind :: Type ( from_ty) , GenericArgKind :: Type ( to_ty) ) = ( from_ty. kind ( ) , to_ty. kind ( ) ) {
14+ match ( from_ty. kind ( ) , to_ty. kind ( ) ) {
15+ ( ty:: Bool , ty:: Bool )
16+ | ( ty:: Char , ty:: Char )
17+ | ( ty:: Int ( _) , ty:: Int ( _) )
18+ | ( ty:: Uint ( _) , ty:: Uint ( _) )
19+ | ( ty:: Float ( _) , ty:: Float ( _) )
20+ | ( ty:: Foreign ( _) , ty:: Foreign ( _) )
21+ | ( ty:: Str , ty:: Str )
22+ | ( ty:: Array ( _, _) , ty:: Array ( _, _) )
23+ | ( ty:: Pat ( _, _) , ty:: Pat ( _, _) )
24+ | ( ty:: Slice ( _) , ty:: Slice ( _) )
25+ | ( ty:: RawPtr ( _, _) , ty:: RawPtr ( _, _) )
26+ | ( ty:: FnDef ( _, _) , ty:: FnDef ( _, _) )
27+ | ( ty:: FnPtr ( _, _) , ty:: FnPtr ( _, _) )
28+ | ( ty:: UnsafeBinder ( _) , ty:: UnsafeBinder ( _) )
29+ | ( ty:: Dynamic ( _, _) , ty:: Dynamic ( _, _) )
30+ | ( ty:: Closure ( _, _) , ty:: Closure ( _, _) )
31+ | ( ty:: CoroutineClosure ( _, _) , ty:: CoroutineClosure ( _, _) )
32+ | ( ty:: Coroutine ( _, _) , ty:: Coroutine ( _, _) )
33+ | ( ty:: CoroutineWitness ( _, _) , ty:: CoroutineWitness ( _, _) )
34+ | ( ty:: Never , ty:: Never )
35+ | ( ty:: Tuple ( _) , ty:: Tuple ( _) )
36+ | ( ty:: Alias ( _, _) , ty:: Alias ( _, _) )
37+ | ( ty:: Param ( _) , ty:: Param ( _) )
38+ | ( ty:: Bound ( _, _) , ty:: Bound ( _, _) )
39+ | ( ty:: Placeholder ( _) , ty:: Placeholder ( _) )
40+ | ( ty:: Infer ( _) , ty:: Infer ( _) )
41+ | ( ty:: Error ( _) , ty:: Error ( _) ) => { } ,
42+ ( ty:: Ref ( _, _, from_mut) , ty:: Ref ( _, _, to_mut) ) => {
43+ if from_mut < to_mut {
44+ span_lint (
45+ cx,
46+ MUTABLE_ADT_ARGUMENT_TRANSMUTE ,
47+ e. span ,
48+ format ! ( "transmute of type argument {from_ty} to {to_ty}" ) ,
49+ ) ;
50+ found = true ;
51+ }
52+ } ,
53+ ( ty:: Adt ( adt1, _) , ty:: Adt ( adt2, _) ) if adt1 == adt2 => { } ,
54+ _ => {
55+ from_ty_walker. skip_current_subtree ( ) ;
56+ to_ty_walker. skip_current_subtree ( ) ;
57+ continue ;
58+ } ,
1659 }
17- } )
18- . filter ( |( from_ty_inner, to_ty_inner) | {
19- if let ( ty:: Ref ( _, _, from_mut) , ty:: Ref ( _, _, to_mut) ) = ( from_ty_inner. kind ( ) , to_ty_inner. kind ( ) )
20- && from_mut < to_mut
21- {
22- span_lint (
23- cx,
24- MUTABLE_ADT_ARGUMENT_TRANSMUTE ,
25- e. span ,
26- format ! ( "transmute of type argument {from_ty_inner} to {from_ty_inner}" ) ,
27- ) ;
28- true
29- } else {
30- false
31- }
32- } )
33- . count ( )
34- > 0
60+ }
61+ }
62+ return found;
3563}
0 commit comments