@@ -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
@@ -65,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
65
72
}
66
73
67
74
if let Some ( ( from_ty_layout, to_ty_layout, e_alloc) ) =
68
- is_cast_to_bigger_memory_layout ( cx, init)
75
+ is_cast_to_bigger_memory_layout ( cx, init, & mut peel_casts )
69
76
{
70
77
cx. emit_spanned_lint (
71
78
INVALID_REFERENCE_CASTING ,
@@ -141,6 +148,7 @@ fn borrow_or_assign<'tcx>(
141
148
fn is_cast_from_ref_to_mut_ptr < ' tcx > (
142
149
cx : & LateContext < ' tcx > ,
143
150
orig_expr : & ' tcx Expr < ' tcx > ,
151
+ mut peel_casts : impl FnMut ( ) -> ( & ' tcx Expr < ' tcx > , bool ) ,
144
152
) -> Option < bool > {
145
153
let end_ty = cx. typeck_results ( ) . node_type ( orig_expr. hir_id ) ;
146
154
@@ -149,7 +157,7 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>(
149
157
return None ;
150
158
}
151
159
152
- let ( e, need_check_freeze) = peel_casts ( cx , orig_expr ) ;
160
+ let ( e, need_check_freeze) = peel_casts ( ) ;
153
161
154
162
let start_ty = cx. typeck_results ( ) . node_type ( e. hir_id ) ;
155
163
if let ty:: Ref ( _, inner_ty, Mutability :: Not ) = start_ty. kind ( ) {
@@ -171,14 +179,15 @@ fn is_cast_from_ref_to_mut_ptr<'tcx>(
171
179
fn is_cast_to_bigger_memory_layout < ' tcx > (
172
180
cx : & LateContext < ' tcx > ,
173
181
orig_expr : & ' tcx Expr < ' tcx > ,
182
+ mut peel_casts : impl FnMut ( ) -> ( & ' tcx Expr < ' tcx > , bool ) ,
174
183
) -> Option < ( TyAndLayout < ' tcx > , TyAndLayout < ' tcx > , Expr < ' tcx > ) > {
175
184
let end_ty = cx. typeck_results ( ) . node_type ( orig_expr. hir_id ) ;
176
185
177
186
let ty:: RawPtr ( TypeAndMut { ty : inner_end_ty, mutbl : _ } ) = end_ty. kind ( ) else {
178
187
return None ;
179
188
} ;
180
189
181
- let ( e, _) = peel_casts ( cx , orig_expr ) ;
190
+ let ( e, _) = peel_casts ( ) ;
182
191
let start_ty = cx. typeck_results ( ) . node_type ( e. hir_id ) ;
183
192
184
193
let ty:: Ref ( _, inner_start_ty, _) = start_ty. kind ( ) else {
0 commit comments