1
1
use super :: NEEDLESS_COLLECT ;
2
2
use clippy_utils:: diagnostics:: { span_lint_and_sugg, span_lint_and_then} ;
3
- use clippy_utils:: source:: snippet;
3
+ use clippy_utils:: source:: { snippet, snippet_with_applicability } ;
4
4
use clippy_utils:: sugg:: Sugg ;
5
- use clippy_utils:: ty:: { is_type_diagnostic_item, match_type } ;
6
- use clippy_utils:: { is_trait_method, path_to_local_id, paths } ;
5
+ use clippy_utils:: ty:: is_type_diagnostic_item;
6
+ use clippy_utils:: { is_trait_method, path_to_local_id} ;
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
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
-
14
13
use rustc_span:: symbol:: { sym, Ident } ;
15
14
use rustc_span:: { MultiSpan , Span } ;
16
15
@@ -28,31 +27,45 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
28
27
if let Some ( generic_args) = chain_method. args;
29
28
if let Some ( GenericArg :: Type ( ref ty) ) = generic_args. args. get( 0 ) ;
30
29
if let Some ( ty) = cx. typeck_results( ) . node_type_opt( ty. hir_id) ;
31
- if is_type_diagnostic_item( cx, ty, sym:: vec_type)
32
- || is_type_diagnostic_item( cx, ty, sym:: vecdeque_type)
33
- || match_type( cx, ty, & paths:: BTREEMAP )
34
- || is_type_diagnostic_item( cx, ty, sym:: hashmap_type) ;
35
- if let Some ( sugg) = match & * method. ident. name. as_str( ) {
36
- "len" => Some ( "count()" . to_string( ) ) ,
37
- "is_empty" => Some ( "next().is_none()" . to_string( ) ) ,
38
- "contains" => {
39
- let contains_arg = snippet( cx, args[ 1 ] . span, "??" ) ;
40
- let ( arg, pred) = contains_arg
41
- . strip_prefix( '&' )
42
- . map_or( ( "&x" , & * contains_arg) , |s| ( "x" , s) ) ;
43
- Some ( format!( "any(|{}| x == {})" , arg, pred) )
44
- }
45
- _ => None ,
46
- } ;
47
30
then {
31
+ let mut applicability = Applicability :: MachineApplicable ;
32
+ let is_empty_sugg = "next().is_none()" . to_string( ) ;
33
+ let method_name = & * method. ident. name. as_str( ) ;
34
+ let sugg = if is_type_diagnostic_item( cx, ty, sym:: vec_type) ||
35
+ is_type_diagnostic_item( cx, ty, sym:: vecdeque_type) ||
36
+ is_type_diagnostic_item( cx, ty, sym:: LinkedList ) ||
37
+ is_type_diagnostic_item( cx, ty, sym:: BinaryHeap ) {
38
+ match method_name {
39
+ "len" => "count()" . to_string( ) ,
40
+ "is_empty" => is_empty_sugg,
41
+ "contains" => {
42
+ let contains_arg = snippet_with_applicability( cx, args[ 1 ] . span, "??" , & mut applicability) ;
43
+ let ( arg, pred) = contains_arg
44
+ . strip_prefix( '&' )
45
+ . map_or( ( "&x" , & * contains_arg) , |s| ( "x" , s) ) ;
46
+ format!( "any(|{}| x == {})" , arg, pred)
47
+ }
48
+ _ => return ,
49
+ }
50
+ }
51
+ else if is_type_diagnostic_item( cx, ty, sym:: BTreeMap ) ||
52
+ is_type_diagnostic_item( cx, ty, sym:: hashmap_type) {
53
+ match method_name {
54
+ "is_empty" => is_empty_sugg,
55
+ _ => return ,
56
+ }
57
+ }
58
+ else {
59
+ return ;
60
+ } ;
48
61
span_lint_and_sugg(
49
62
cx,
50
63
NEEDLESS_COLLECT ,
51
64
method0_span. with_hi( expr. span. hi( ) ) ,
52
65
NEEDLESS_COLLECT_MSG ,
53
66
"replace with" ,
54
67
sugg,
55
- Applicability :: MachineApplicable ,
68
+ applicability ,
56
69
) ;
57
70
}
58
71
}
@@ -86,7 +99,7 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
86
99
if is_type_diagnostic_item( cx, ty, sym:: vec_type) ||
87
100
is_type_diagnostic_item( cx, ty, sym:: vecdeque_type) ||
88
101
is_type_diagnostic_item( cx, ty, sym:: BinaryHeap ) ||
89
- match_type ( cx, ty, & paths :: LINKED_LIST ) ;
102
+ is_type_diagnostic_item ( cx, ty, sym :: LinkedList ) ;
90
103
if let Some ( iter_calls) = detect_iter_and_into_iters( block, * ident) ;
91
104
if let [ iter_call] = & * iter_calls;
92
105
then {
0 commit comments