1
1
use super :: EXPLICIT_ITER_LOOP ;
2
2
use clippy_utils:: diagnostics:: span_lint_and_sugg;
3
- use clippy_utils:: is_trait_method;
4
3
use clippy_utils:: msrvs:: { self , Msrv } ;
5
4
use clippy_utils:: source:: snippet_with_applicability;
6
- use clippy_utils:: ty:: { implements_trait_with_env, make_normalized_projection_with_regions, normalize_with_regions,
7
- make_normalized_projection, implements_trait, is_copy} ;
5
+ use clippy_utils:: ty:: {
6
+ implements_trait, implements_trait_with_env, is_copy, make_normalized_projection,
7
+ make_normalized_projection_with_regions, normalize_with_regions,
8
+ } ;
8
9
use rustc_errors:: Applicability ;
9
10
use rustc_hir:: { Expr , Mutability } ;
10
11
use rustc_lint:: LateContext ;
11
12
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow , AutoBorrowMutability } ;
12
- use rustc_middle:: ty:: { self , EarlyBinder , TypeAndMut , Ty } ;
13
+ use rustc_middle:: ty:: { self , EarlyBinder , Ty , TypeAndMut } ;
13
14
use rustc_span:: sym;
14
15
15
- pub ( super ) fn check ( cx : & LateContext < ' _ > , self_arg : & Expr < ' _ > , call_expr : & Expr < ' _ > , method_name : & str , msrv : & Msrv ) {
16
- let borrow_kind = match method_name {
17
- "iter" | "iter_mut" => match is_ref_iterable ( cx, self_arg, call_expr) {
18
- Some ( ( kind, ty) ) => {
19
- if let ty:: Array ( _, count) = * ty. peel_refs ( ) . kind ( ) {
20
- if !ty. is_ref ( ) {
21
- if !msrv. meets ( msrvs:: ARRAY_INTO_ITERATOR ) {
22
- return ;
23
- }
24
- } else if count. try_eval_target_usize ( cx. tcx , cx. param_env ) . map_or ( true , |x| x > 32 )
25
- && !msrv. meets ( msrvs:: ARRAY_IMPL_ANY_LEN )
26
- {
27
- return
28
- }
29
- }
30
- kind
31
- } ,
32
- None => return ,
33
- } ,
34
- "into_iter" if is_trait_method ( cx, call_expr, sym:: IntoIterator ) => {
35
- let receiver_ty = cx. typeck_results ( ) . expr_ty ( self_arg) ;
36
- let receiver_ty_adjusted = cx. typeck_results ( ) . expr_ty_adjusted ( self_arg) ;
37
- let ref_receiver_ty = cx. tcx . mk_ref (
38
- cx. tcx . lifetimes . re_erased ,
39
- ty:: TypeAndMut {
40
- ty : receiver_ty,
41
- mutbl : Mutability :: Not ,
42
- } ,
43
- ) ;
44
- if receiver_ty_adjusted == ref_receiver_ty {
45
- AdjustKind :: None
46
- } else {
16
+ pub ( super ) fn check ( cx : & LateContext < ' _ > , self_arg : & Expr < ' _ > , call_expr : & Expr < ' _ > , msrv : & Msrv ) {
17
+ let Some ( ( adjust, ty) ) = is_ref_iterable ( cx, self_arg, call_expr) else {
18
+ return ;
19
+ } ;
20
+ if let ty:: Array ( _, count) = * ty. peel_refs ( ) . kind ( ) {
21
+ if !ty. is_ref ( ) {
22
+ if !msrv. meets ( msrvs:: ARRAY_INTO_ITERATOR ) {
47
23
return ;
48
24
}
49
- } ,
50
- _ => return ,
51
- } ;
25
+ } else if count
26
+ . try_eval_target_usize ( cx. tcx , cx. param_env )
27
+ . map_or ( true , |x| x > 32 )
28
+ && !msrv. meets ( msrvs:: ARRAY_IMPL_ANY_LEN )
29
+ {
30
+ return ;
31
+ }
32
+ }
52
33
53
34
let mut applicability = Applicability :: MachineApplicable ;
54
35
let object = snippet_with_applicability ( cx, self_arg. span , "_" , & mut applicability) ;
55
- let prefix = match borrow_kind {
36
+ let prefix = match adjust {
56
37
AdjustKind :: None => "" ,
57
38
AdjustKind :: Borrow => "&" ,
58
39
AdjustKind :: BorrowMut => "&mut " ,
@@ -105,7 +86,11 @@ impl AdjustKind {
105
86
106
87
/// Checks if an `iter` or `iter_mut` call returns `IntoIterator::IntoIter`. Returns how the
107
88
/// argument needs to be adjusted.
108
- fn is_ref_iterable < ' tcx > ( cx : & LateContext < ' tcx > , self_arg : & Expr < ' _ > , call_expr : & Expr < ' _ > ) -> Option < ( AdjustKind , Ty < ' tcx > ) > {
89
+ fn is_ref_iterable < ' tcx > (
90
+ cx : & LateContext < ' tcx > ,
91
+ self_arg : & Expr < ' _ > ,
92
+ call_expr : & Expr < ' _ > ,
93
+ ) -> Option < ( AdjustKind , Ty < ' tcx > ) > {
109
94
let typeck = cx. typeck_results ( ) ;
110
95
if let Some ( trait_id) = cx. tcx . get_diagnostic_item ( sym:: IntoIterator )
111
96
&& let Some ( fn_id) = typeck. type_dependent_def_id ( call_expr. hir_id )
@@ -158,10 +143,18 @@ fn is_ref_iterable<'tcx>(cx: &LateContext<'tcx>, self_arg: &Expr<'_>, call_expr:
158
143
159
144
match adjustments {
160
145
[ ] => Some ( ( AdjustKind :: None , self_ty) ) ,
161
- & [ Adjustment { kind : Adjust :: Deref ( _) , ..} , Adjustment { kind : Adjust :: Borrow ( AutoBorrow :: Ref ( _, mutbl) ) , target } , ..] => {
146
+ & [
147
+ Adjustment { kind : Adjust :: Deref ( _) , ..} ,
148
+ Adjustment {
149
+ kind : Adjust :: Borrow ( AutoBorrow :: Ref ( _, mutbl) ) ,
150
+ target,
151
+ } ,
152
+ ..
153
+ ] => {
162
154
if target != self_ty
163
155
&& implements_trait ( cx, target, trait_id, & [ ] )
164
- && let Some ( ty) = make_normalized_projection ( cx. tcx , cx. param_env , trait_id, sym ! ( IntoIter ) , [ target] )
156
+ && let Some ( ty) =
157
+ make_normalized_projection ( cx. tcx , cx. param_env , trait_id, sym ! ( IntoIter ) , [ target] )
165
158
&& ty == res_ty
166
159
{
167
160
Some ( ( AdjustKind :: reborrow ( mutbl) , target) )
@@ -172,18 +165,26 @@ fn is_ref_iterable<'tcx>(cx: &LateContext<'tcx>, self_arg: &Expr<'_>, call_expr:
172
165
& [ Adjustment { kind : Adjust :: Deref ( _) , target } , ..] => {
173
166
if is_copy ( cx, target)
174
167
&& implements_trait ( cx, target, trait_id, & [ ] )
175
- && let Some ( ty) = make_normalized_projection ( cx. tcx , cx. param_env , trait_id, sym ! ( IntoIter ) , [ target] )
168
+ && let Some ( ty) =
169
+ make_normalized_projection ( cx. tcx , cx. param_env , trait_id, sym ! ( IntoIter ) , [ target] )
176
170
&& ty == res_ty
177
171
{
178
172
Some ( ( AdjustKind :: Deref , target) )
179
173
} else {
180
174
None
181
175
}
182
176
}
183
- & [ Adjustment { kind : Adjust :: Borrow ( AutoBorrow :: Ref ( _, mutbl) ) , target } , ..] => {
177
+ & [
178
+ Adjustment {
179
+ kind : Adjust :: Borrow ( AutoBorrow :: Ref ( _, mutbl) ) ,
180
+ target,
181
+ } ,
182
+ ..
183
+ ] => {
184
184
if self_ty. is_ref ( )
185
185
&& implements_trait ( cx, target, trait_id, & [ ] )
186
- && let Some ( ty) = make_normalized_projection ( cx. tcx , cx. param_env , trait_id, sym ! ( IntoIter ) , [ target] )
186
+ && let Some ( ty) =
187
+ make_normalized_projection ( cx. tcx , cx. param_env , trait_id, sym ! ( IntoIter ) , [ target] )
187
188
&& ty == res_ty
188
189
{
189
190
Some ( ( AdjustKind :: auto_borrow ( mutbl) , target) )
0 commit comments