@@ -7,9 +7,10 @@ use clippy_utils::{is_trait_method, path_to_local_id, paths};
7
7
use if_chain:: if_chain;
8
8
use rustc_errors:: Applicability ;
9
9
use rustc_hir:: intravisit:: { walk_block, walk_expr, NestedVisitorMap , Visitor } ;
10
- use rustc_hir:: { Block , Expr , ExprKind , GenericArg , HirId , Local , Pat , PatKind , QPath , StmtKind } ;
10
+ use rustc_hir:: { Block , Expr , ExprKind , GenericArg , GenericArgs , HirId , Local , Pat , PatKind , QPath , StmtKind , Ty } ;
11
11
use rustc_lint:: LateContext ;
12
12
use rustc_middle:: hir:: map:: Map ;
13
+
13
14
use rustc_span:: symbol:: { sym, Ident } ;
14
15
use rustc_span:: { MultiSpan , Span } ;
15
16
@@ -26,7 +27,7 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
26
27
if chain_method. ident. name == sym!( collect) && is_trait_method( cx, & args[ 0 ] , sym:: Iterator ) ;
27
28
if let Some ( generic_args) = chain_method. args;
28
29
if let Some ( GenericArg :: Type ( ref ty) ) = generic_args. args. get( 0 ) ;
29
- let ty = cx. typeck_results( ) . node_type ( ty. hir_id) ;
30
+ if let Some ( ty ) = cx. typeck_results( ) . node_type_opt ( ty. hir_id) ;
30
31
if is_type_diagnostic_item( cx, ty, sym:: vec_type)
31
32
|| is_type_diagnostic_item( cx, ty, sym:: vecdeque_type)
32
33
|| match_type( cx, ty, & paths:: BTREEMAP )
@@ -58,20 +59,33 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
58
59
}
59
60
60
61
fn check_needless_collect_indirect_usage < ' tcx > ( expr : & ' tcx Expr < ' _ > , cx : & LateContext < ' tcx > ) {
62
+ fn get_hir_id < ' tcx > ( ty : Option < & Ty < ' tcx > > , method_args : Option < & GenericArgs < ' tcx > > ) -> Option < HirId > {
63
+ if let Some ( ty) = ty {
64
+ return Some ( ty. hir_id ) ;
65
+ }
66
+
67
+ if let Some ( generic_args) = method_args {
68
+ if let Some ( GenericArg :: Type ( ref ty) ) = generic_args. args . get ( 0 ) {
69
+ return Some ( ty. hir_id ) ;
70
+ }
71
+ }
72
+
73
+ None
74
+ }
61
75
if let ExprKind :: Block ( block, _) = expr. kind {
62
76
for stmt in block. stmts {
63
77
if_chain ! {
64
78
if let StmtKind :: Local (
65
79
Local { pat: Pat { hir_id: pat_id, kind: PatKind :: Binding ( _, _, ident, .. ) , .. } ,
66
- init: Some ( init_expr) , .. }
80
+ init: Some ( init_expr) , ty , .. }
67
81
) = stmt. kind;
68
82
if let ExprKind :: MethodCall ( method_name, collect_span, & [ ref iter_source] , ..) = init_expr. kind;
69
83
if method_name. ident. name == sym!( collect) && is_trait_method( cx, init_expr, sym:: Iterator ) ;
70
- if let Some ( generic_args) = method_name. args;
71
- if let Some ( GenericArg :: Type ( ref ty) ) = generic_args. args. get( 0 ) ;
72
- if let ty = cx. typeck_results( ) . node_type( ty. hir_id) ;
84
+ if let Some ( hir_id) = get_hir_id( * ty, method_name. args) ;
85
+ if let Some ( ty) = cx. typeck_results( ) . node_type_opt( hir_id) ;
73
86
if is_type_diagnostic_item( cx, ty, sym:: vec_type) ||
74
87
is_type_diagnostic_item( cx, ty, sym:: vecdeque_type) ||
88
+ is_type_diagnostic_item( cx, ty, sym:: BinaryHeap ) ||
75
89
match_type( cx, ty, & paths:: LINKED_LIST ) ;
76
90
if let Some ( iter_calls) = detect_iter_and_into_iters( block, * ident) ;
77
91
if let [ iter_call] = & * iter_calls;
0 commit comments