@@ -18,13 +18,11 @@ mod while_immutable_condition;
18
18
mod while_let_loop;
19
19
mod while_let_on_iterator;
20
20
21
- use crate :: utils:: { higher, is_type_diagnostic_item , match_trait_method , match_type , paths } ;
22
- use rustc_hir:: { Expr , ExprKind , LoopSource , Mutability , Pat } ;
21
+ use crate :: utils:: higher;
22
+ use rustc_hir:: { Expr , ExprKind , LoopSource , Pat } ;
23
23
use rustc_lint:: { LateContext , LateLintPass } ;
24
- use rustc_middle:: ty:: { self , Ty , TyS } ;
25
24
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
26
25
use rustc_span:: source_map:: Span ;
27
- use rustc_span:: symbol:: sym;
28
26
use utils:: { get_span_of_entire_for_loop, make_iterator_snippet, IncrementVisitor , InitializeVisitor } ;
29
27
30
28
declare_clippy_lint ! {
@@ -603,67 +601,27 @@ fn check_for_loop<'tcx>(
603
601
604
602
fn check_for_loop_arg ( cx : & LateContext < ' _ > , pat : & Pat < ' _ > , arg : & Expr < ' _ > , expr : & Expr < ' _ > ) {
605
603
let mut next_loop_linted = false ; // whether or not ITER_NEXT_LOOP lint was used
604
+
606
605
if let ExprKind :: MethodCall ( ref method, _, ref args, _) = arg. kind {
607
606
// just the receiver, no arguments
608
607
if args. len ( ) == 1 {
609
608
let method_name = & * method. ident . as_str ( ) ;
610
609
// check for looping over x.iter() or x.iter_mut(), could use &x or &mut x
611
- if method_name == "iter" || method_name == "iter_mut" {
612
- if is_ref_iterable_type ( cx, & args[ 0 ] ) {
610
+ match method_name {
611
+ "iter" | "iter_mut" => explicit_iter_loop:: check ( cx, args, arg, method_name) ,
612
+ "into_iter" => {
613
613
explicit_iter_loop:: check ( cx, args, arg, method_name) ;
614
- }
615
- } else if method_name == "into_iter" && match_trait_method ( cx, arg, & paths:: INTO_ITERATOR ) {
616
- let receiver_ty = cx. typeck_results ( ) . expr_ty ( & args[ 0 ] ) ;
617
- let receiver_ty_adjusted = cx. typeck_results ( ) . expr_ty_adjusted ( & args[ 0 ] ) ;
618
- if TyS :: same_type ( receiver_ty, receiver_ty_adjusted) {
619
614
explicit_into_iter_loop:: check ( cx, args, arg) ;
620
- } else {
621
- let ref_receiver_ty = cx. tcx . mk_ref (
622
- cx. tcx . lifetimes . re_erased ,
623
- ty:: TypeAndMut {
624
- ty : receiver_ty,
625
- mutbl : Mutability :: Not ,
626
- } ,
627
- ) ;
628
- if TyS :: same_type ( receiver_ty_adjusted, ref_receiver_ty) {
629
- explicit_iter_loop:: check ( cx, args, arg, method_name)
630
- }
631
- }
632
- } else if method_name == "next" && match_trait_method ( cx, arg, & paths:: ITERATOR ) {
633
- iter_next_loop:: check ( cx, expr) ;
634
- next_loop_linted = true ;
615
+ } ,
616
+ "next" => {
617
+ next_loop_linted = iter_next_loop:: check ( cx, arg, expr) ;
618
+ } ,
619
+ _ => { } ,
635
620
}
636
621
}
637
622
}
623
+
638
624
if !next_loop_linted {
639
625
for_loops_over_fallibles:: check ( cx, pat, arg) ;
640
626
}
641
627
}
642
-
643
- /// Returns `true` if the type of expr is one that provides `IntoIterator` impls
644
- /// for `&T` and `&mut T`, such as `Vec`.
645
- #[ rustfmt:: skip]
646
- fn is_ref_iterable_type ( cx : & LateContext < ' _ > , e : & Expr < ' _ > ) -> bool {
647
- // no walk_ptrs_ty: calling iter() on a reference can make sense because it
648
- // will allow further borrows afterwards
649
- let ty = cx. typeck_results ( ) . expr_ty ( e) ;
650
- is_iterable_array ( ty, cx) ||
651
- is_type_diagnostic_item ( cx, ty, sym:: vec_type) ||
652
- match_type ( cx, ty, & paths:: LINKED_LIST ) ||
653
- is_type_diagnostic_item ( cx, ty, sym ! ( hashmap_type) ) ||
654
- is_type_diagnostic_item ( cx, ty, sym ! ( hashset_type) ) ||
655
- is_type_diagnostic_item ( cx, ty, sym ! ( vecdeque_type) ) ||
656
- match_type ( cx, ty, & paths:: BINARY_HEAP ) ||
657
- match_type ( cx, ty, & paths:: BTREEMAP ) ||
658
- match_type ( cx, ty, & paths:: BTREESET )
659
- }
660
-
661
- fn is_iterable_array < ' tcx > ( ty : Ty < ' tcx > , cx : & LateContext < ' tcx > ) -> bool {
662
- // IntoIterator is currently only implemented for array sizes <= 32 in rustc
663
- match ty. kind ( ) {
664
- ty:: Array ( _, n) => n
665
- . try_eval_usize ( cx. tcx , cx. param_env )
666
- . map_or ( false , |val| ( 0 ..=32 ) . contains ( & val) ) ,
667
- _ => false ,
668
- }
669
- }
0 commit comments