@@ -42,8 +42,15 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
42
42
let init = cx. expr_or_init ( e) ;
43
43
let orig_cast = if init. span != e. span { Some ( init. span ) } else { None } ;
44
44
45
+ // small cache to avoid recomputing needlesly computing peel_casts of init
46
+ let mut peel_casts = {
47
+ let mut peel_casts_cache = None ;
48
+ move || * peel_casts_cache. get_or_insert_with ( || peel_casts ( cx, init) )
49
+ } ;
50
+
45
51
if matches ! ( pat, PatternKind :: Borrow { mutbl: Mutability :: Mut } | PatternKind :: Assign )
46
- && let Some ( ty_has_interior_mutability) = is_cast_from_ref_to_mut_ptr ( cx, init)
52
+ && let Some ( ty_has_interior_mutability) =
53
+ is_cast_from_ref_to_mut_ptr ( cx, init, & mut peel_casts)
47
54
{
48
55
let ty_has_interior_mutability = ty_has_interior_mutability. then_some ( ( ) ) ;
49
56
@@ -64,7 +71,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
64
71
) ;
65
72
}
66
73
67
- if let Some ( ( from_ty_layout, to_ty_layout) ) = is_cast_to_bigger_memory_layout ( cx, init)
74
+ if let Some ( ( from_ty_layout, to_ty_layout) ) =
75
+ is_cast_to_bigger_memory_layout ( cx, init, & mut peel_casts)
68
76
{
69
77
cx. emit_spanned_lint (
70
78
INVALID_REFERENCE_CASTING ,
@@ -141,6 +149,7 @@ fn borrow_or_assign<'tcx>(
141
149
fn is_cast_from_ref_to_mut_ptr < ' tcx > (
142
150
cx : & LateContext < ' tcx > ,
143
151
orig_expr : & ' tcx Expr < ' tcx > ,
152
+ mut peel_casts : impl FnMut ( ) -> ( & ' tcx Expr < ' tcx > , bool ) ,
144
153
) -> Option < bool > {
145
154
let end_ty = cx. typeck_results ( ) . node_type ( orig_expr. hir_id ) ;
146
155
@@ -149,7 +158,7 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>(
149
158
return None ;
150
159
}
151
160
152
- let ( e, need_check_freeze) = peel_casts ( cx , orig_expr ) ;
161
+ let ( e, need_check_freeze) = peel_casts ( ) ;
153
162
154
163
let start_ty = cx. typeck_results ( ) . node_type ( e. hir_id ) ;
155
164
if let ty:: Ref ( _, inner_ty, Mutability :: Not ) = start_ty. kind ( ) {
@@ -171,14 +180,15 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>(
171
180
fn is_cast_to_bigger_memory_layout < ' tcx > (
172
181
cx : & LateContext < ' tcx > ,
173
182
orig_expr : & ' tcx Expr < ' tcx > ,
183
+ mut peel_casts : impl FnMut ( ) -> ( & ' tcx Expr < ' tcx > , bool ) ,
174
184
) -> Option < ( TyAndLayout < ' tcx > , TyAndLayout < ' tcx > ) > {
175
185
let end_ty = cx. typeck_results ( ) . node_type ( orig_expr. hir_id ) ;
176
186
177
187
let ty:: RawPtr ( TypeAndMut { ty : inner_end_ty, mutbl : _ } ) = end_ty. kind ( ) else {
178
188
return None ;
179
189
} ;
180
190
181
- let ( e, _) = peel_casts ( cx , orig_expr ) ;
191
+ let ( e, _) = peel_casts ( ) ;
182
192
let start_ty = cx. typeck_results ( ) . node_type ( e. hir_id ) ;
183
193
184
194
let ty:: Ref ( _, inner_start_ty, _) = start_ty. kind ( ) else {
0 commit comments