11use super :: EXPLICIT_ITER_LOOP ;
22use clippy_utils:: diagnostics:: span_lint_and_sugg;
3- use clippy_utils:: is_trait_method;
43use clippy_utils:: msrvs:: { self , Msrv } ;
54use 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+ } ;
89use rustc_errors:: Applicability ;
910use rustc_hir:: { Expr , Mutability } ;
1011use rustc_lint:: LateContext ;
1112use 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 } ;
1314use rustc_span:: sym;
1415
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 ) {
4723 return ;
4824 }
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+ }
5233
5334 let mut applicability = Applicability :: MachineApplicable ;
5435 let object = snippet_with_applicability ( cx, self_arg. span , "_" , & mut applicability) ;
55- let prefix = match borrow_kind {
36+ let prefix = match adjust {
5637 AdjustKind :: None => "" ,
5738 AdjustKind :: Borrow => "&" ,
5839 AdjustKind :: BorrowMut => "&mut " ,
@@ -105,7 +86,11 @@ impl AdjustKind {
10586
10687/// Checks if an `iter` or `iter_mut` call returns `IntoIterator::IntoIter`. Returns how the
10788/// 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 > ) > {
10994 let typeck = cx. typeck_results ( ) ;
11095 if let Some ( trait_id) = cx. tcx . get_diagnostic_item ( sym:: IntoIterator )
11196 && 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:
158143
159144 match adjustments {
160145 [ ] => 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+ ] => {
162154 if target != self_ty
163155 && 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] )
165158 && ty == res_ty
166159 {
167160 Some ( ( AdjustKind :: reborrow ( mutbl) , target) )
@@ -172,18 +165,26 @@ fn is_ref_iterable<'tcx>(cx: &LateContext<'tcx>, self_arg: &Expr<'_>, call_expr:
172165 & [ Adjustment { kind : Adjust :: Deref ( _) , target } , ..] => {
173166 if is_copy ( cx, target)
174167 && 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] )
176170 && ty == res_ty
177171 {
178172 Some ( ( AdjustKind :: Deref , target) )
179173 } else {
180174 None
181175 }
182176 }
183- & [ Adjustment { kind : Adjust :: Borrow ( AutoBorrow :: Ref ( _, mutbl) ) , target } , ..] => {
177+ & [
178+ Adjustment {
179+ kind : Adjust :: Borrow ( AutoBorrow :: Ref ( _, mutbl) ) ,
180+ target,
181+ } ,
182+ ..
183+ ] => {
184184 if self_ty. is_ref ( )
185185 && 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] )
187188 && ty == res_ty
188189 {
189190 Some ( ( AdjustKind :: auto_borrow ( mutbl) , target) )
0 commit comments