1
- use crate :: utils:: { is_type_diagnostic_item, match_def_path, paths, snippet, span_lint_and_sugg} ;
1
+ use crate :: utils:: {
2
+ is_type_diagnostic_item, match_def_path, path_to_local, path_to_local_id, paths, snippet, span_lint_and_sugg,
3
+ } ;
2
4
use if_chain:: if_chain;
3
5
use rustc_ast:: ast:: LitKind ;
4
6
use rustc_errors:: Applicability ;
5
- use rustc_hir:: { BindingAnnotation , Block , Expr , ExprKind , Local , PatKind , QPath , Stmt , StmtKind } ;
7
+ use rustc_hir:: { BindingAnnotation , Block , Expr , ExprKind , HirId , Local , PatKind , QPath , Stmt , StmtKind } ;
6
8
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
7
9
use rustc_middle:: lint:: in_external_macro;
8
10
use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
9
- use rustc_span:: { symbol:: sym, Span , Symbol } ;
11
+ use rustc_span:: { symbol:: sym, Span } ;
10
12
use std:: convert:: TryInto ;
11
13
12
14
declare_clippy_lint ! {
@@ -45,8 +47,8 @@ enum VecInitKind {
45
47
WithCapacity ( u64 ) ,
46
48
}
47
49
struct VecPushSearcher {
50
+ local_id : HirId ,
48
51
init : VecInitKind ,
49
- name : Symbol ,
50
52
lhs_is_local : bool ,
51
53
lhs_span : Span ,
52
54
err_span : Span ,
@@ -81,17 +83,20 @@ impl VecPushSearcher {
81
83
}
82
84
83
85
impl LateLintPass < ' _ > for VecInitThenPush {
84
- fn check_local ( & mut self , cx : & LateContext < ' tcx > , local : & ' tcx Local < ' tcx > ) {
86
+ fn check_block ( & mut self , _ : & LateContext < ' tcx > , _ : & ' tcx Block < ' tcx > ) {
85
87
self . searcher = None ;
88
+ }
89
+
90
+ fn check_local ( & mut self , cx : & LateContext < ' tcx > , local : & ' tcx Local < ' tcx > ) {
86
91
if_chain ! {
87
92
if !in_external_macro( cx. sess( ) , local. span) ;
88
93
if let Some ( init) = local. init;
89
- if let PatKind :: Binding ( BindingAnnotation :: Mutable , _ , ident , None ) = local. pat. kind;
94
+ if let PatKind :: Binding ( BindingAnnotation :: Mutable , id , _ , None ) = local. pat. kind;
90
95
if let Some ( init_kind) = get_vec_init_kind( cx, init) ;
91
96
then {
92
97
self . searcher = Some ( VecPushSearcher {
98
+ local_id: id,
93
99
init: init_kind,
94
- name: ident. name,
95
100
lhs_is_local: true ,
96
101
lhs_span: local. ty. map_or( local. pat. span, |t| local. pat. span. to( t. span) ) ,
97
102
err_span: local. span,
@@ -106,13 +111,12 @@ impl LateLintPass<'_> for VecInitThenPush {
106
111
if_chain ! {
107
112
if !in_external_macro( cx. sess( ) , expr. span) ;
108
113
if let ExprKind :: Assign ( left, right, _) = expr. kind;
109
- if let ExprKind :: Path ( QPath :: Resolved ( _, path) ) = left. kind;
110
- if let Some ( name) = path. segments. get( 0 ) ;
114
+ if let Some ( id) = path_to_local( left) ;
111
115
if let Some ( init_kind) = get_vec_init_kind( cx, right) ;
112
116
then {
113
117
self . searcher = Some ( VecPushSearcher {
118
+ local_id: id,
114
119
init: init_kind,
115
- name: name. ident. name,
116
120
lhs_is_local: false ,
117
121
lhs_span: left. span,
118
122
err_span: expr. span,
@@ -128,10 +132,8 @@ impl LateLintPass<'_> for VecInitThenPush {
128
132
if_chain ! {
129
133
if let StmtKind :: Expr ( expr) | StmtKind :: Semi ( expr) = stmt. kind;
130
134
if let ExprKind :: MethodCall ( path, _, [ self_arg, _] , _) = expr. kind;
135
+ if path_to_local_id( self_arg, searcher. local_id) ;
131
136
if path. ident. name. as_str( ) == "push" ;
132
- if let ExprKind :: Path ( QPath :: Resolved ( _, self_path) ) = self_arg. kind;
133
- if let [ self_name] = self_path. segments;
134
- if self_name. ident. name == searcher. name;
135
137
then {
136
138
self . searcher = Some ( VecPushSearcher {
137
139
found: searcher. found + 1 ,
0 commit comments