@@ -38,8 +38,8 @@ pub struct MacroRefData {
38
38
}
39
39
40
40
impl MacroRefData {
41
- pub fn new ( name : & str , span : Span , ecx : & LateContext < ' _ , ' _ > ) -> Self {
42
- let mut path = ecx . sess ( ) . source_map ( ) . span_to_filename ( span ) . to_string ( ) ;
41
+ pub fn new ( name : & str , callee : Span , cx : & LateContext < ' _ , ' _ > ) -> Self {
42
+ let mut path = cx . sess ( ) . source_map ( ) . span_to_filename ( callee ) . to_string ( ) ;
43
43
44
44
// std lib paths are <::std::module::file type>
45
45
// so remove brackets, space and type.
@@ -63,142 +63,126 @@ pub struct MacroUseImports {
63
63
imports : Vec < ( String , Span ) > ,
64
64
/// the span of the macro reference, kept to ensure only one reference is used per macro call.
65
65
collected : FxHashSet < Span > ,
66
- mac_refs : Vec < ( Span , MacroRefData ) > ,
66
+ mac_refs : Vec < MacroRefData > ,
67
67
}
68
68
69
69
impl_lint_pass ! ( MacroUseImports => [ MACRO_USE_IMPORTS ] ) ;
70
70
71
+ impl MacroUseImports {
72
+ fn push_unique_macro ( & mut self , cx : & LateContext < ' _ , ' _ > , name : & str , call_site : Span , callee : Span ) {
73
+ if !self . collected . contains ( & call_site) {
74
+ let name = if name. contains ( "::" ) {
75
+ name. split ( "::" ) . last ( ) . unwrap ( ) . to_string ( )
76
+ } else {
77
+ name. to_string ( )
78
+ } ;
79
+
80
+ self . mac_refs . push ( MacroRefData :: new ( & name, callee, cx) ) ;
81
+ self . collected . insert ( call_site) ;
82
+ }
83
+ }
84
+
85
+ fn push_unique_macro_pat_ty ( & mut self , cx : & LateContext < ' _ , ' _ > , name : & str , call_site : Span , callee : Span ) {
86
+ if !self . collected . contains ( & call_site) {
87
+ self . mac_refs . push ( MacroRefData :: new ( & name, callee, cx) ) ;
88
+ self . collected . insert ( call_site) ;
89
+ }
90
+ }
91
+ }
92
+
71
93
impl < ' l , ' txc > LateLintPass < ' l , ' txc > for MacroUseImports {
72
- fn check_item ( & mut self , lcx : & LateContext < ' _ , ' _ > , item : & hir:: Item < ' _ > ) {
94
+ fn check_item ( & mut self , cx : & LateContext < ' _ , ' _ > , item : & hir:: Item < ' _ > ) {
73
95
if_chain ! {
74
- if lcx . sess( ) . opts. edition == Edition :: Edition2018 ;
96
+ if cx . sess( ) . opts. edition == Edition :: Edition2018 ;
75
97
if let hir:: ItemKind :: Use ( path, _kind) = & item. kind;
76
98
if let Some ( mac_attr) = item
77
99
. attrs
78
100
. iter( )
79
101
. find( |attr| attr. ident( ) . map( |s| s. to_string( ) ) == Some ( "macro_use" . to_string( ) ) ) ;
80
102
if let Res :: Def ( DefKind :: Mod , id) = path. res;
81
103
then {
82
- for kid in lcx . tcx. item_children( id) . iter( ) {
104
+ for kid in cx . tcx. item_children( id) . iter( ) {
83
105
if let Res :: Def ( DefKind :: Macro ( _mac_type) , mac_id) = kid. res {
84
106
let span = mac_attr. span;
85
- self . imports. push( ( lcx . tcx. def_path_str( mac_id) , span) ) ;
107
+ self . imports. push( ( cx . tcx. def_path_str( mac_id) , span) ) ;
86
108
}
87
109
}
88
110
} else {
89
- if in_macro( item. span) {
90
- let call_site = item. span. source_callsite( ) ;
91
- let name = snippet( lcx, lcx. sess( ) . source_map( ) . span_until_char( call_site, '!' ) , "_" ) ;
92
- if let Some ( callee) = item. span. source_callee( ) {
93
- if !self . collected. contains( & call_site) {
94
- self . mac_refs. push( ( call_site, MacroRefData :: new( & name, callee. def_site, lcx) ) ) ;
95
- self . collected. insert( call_site) ;
111
+ if in_macro( item. span) {
112
+ let call_site = item. span. source_callsite( ) ;
113
+ let name = snippet( cx, cx. sess( ) . source_map( ) . span_until_char( call_site, '!' ) , "_" ) ;
114
+ if let Some ( callee) = item. span. source_callee( ) {
115
+ if !self . collected. contains( & call_site) {
116
+ self . mac_refs. push( MacroRefData :: new( & name, callee. def_site, cx) ) ;
117
+ self . collected. insert( call_site) ;
118
+ }
96
119
}
97
120
}
98
- }
99
121
}
100
122
}
101
123
}
102
- fn check_attribute ( & mut self , lcx : & LateContext < ' _ , ' _ > , attr : & ast:: Attribute ) {
124
+ fn check_attribute ( & mut self , cx : & LateContext < ' _ , ' _ > , attr : & ast:: Attribute ) {
103
125
if in_macro ( attr. span ) {
104
126
let call_site = attr. span . source_callsite ( ) ;
105
- let name = snippet ( lcx , lcx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
127
+ let name = snippet ( cx , cx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
106
128
if let Some ( callee) = attr. span . source_callee ( ) {
107
- if !self . collected . contains ( & call_site) {
108
- let name = if name. contains ( "::" ) {
109
- name. split ( "::" ) . last ( ) . unwrap ( ) . to_string ( )
110
- } else {
111
- name. to_string ( )
112
- } ;
113
-
114
- self . mac_refs
115
- . push ( ( call_site, MacroRefData :: new ( & name, callee. def_site , lcx) ) ) ;
116
- self . collected . insert ( call_site) ;
117
- }
129
+ self . push_unique_macro ( cx, & name, call_site, callee. def_site ) ;
118
130
}
119
131
}
120
132
}
121
- fn check_expr ( & mut self , lcx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr < ' _ > ) {
133
+ fn check_expr ( & mut self , cx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr < ' _ > ) {
122
134
if in_macro ( expr. span ) {
123
135
let call_site = expr. span . source_callsite ( ) ;
124
- let name = snippet ( lcx , lcx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
136
+ let name = snippet ( cx , cx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
125
137
if let Some ( callee) = expr. span . source_callee ( ) {
126
- if !self . collected . contains ( & call_site) {
127
- let name = if name. contains ( "::" ) {
128
- name. split ( "::" ) . last ( ) . unwrap ( ) . to_string ( )
129
- } else {
130
- name. to_string ( )
131
- } ;
132
-
133
- self . mac_refs
134
- . push ( ( call_site, MacroRefData :: new ( & name, callee. def_site , lcx) ) ) ;
135
- self . collected . insert ( call_site) ;
136
- }
138
+ self . push_unique_macro ( cx, & name, call_site, callee. def_site ) ;
137
139
}
138
140
}
139
141
}
140
- fn check_stmt ( & mut self , lcx : & LateContext < ' _ , ' _ > , stmt : & hir:: Stmt < ' _ > ) {
142
+ fn check_stmt ( & mut self , cx : & LateContext < ' _ , ' _ > , stmt : & hir:: Stmt < ' _ > ) {
141
143
if in_macro ( stmt. span ) {
142
144
let call_site = stmt. span . source_callsite ( ) ;
143
- let name = snippet ( lcx , lcx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
145
+ let name = snippet ( cx , cx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
144
146
if let Some ( callee) = stmt. span . source_callee ( ) {
145
- if !self . collected . contains ( & call_site) {
146
- let name = if name. contains ( "::" ) {
147
- name. split ( "::" ) . last ( ) . unwrap ( ) . to_string ( )
148
- } else {
149
- name. to_string ( )
150
- } ;
151
-
152
- self . mac_refs
153
- . push ( ( call_site, MacroRefData :: new ( & name, callee. def_site , lcx) ) ) ;
154
- self . collected . insert ( call_site) ;
155
- }
147
+ self . push_unique_macro ( cx, & name, call_site, callee. def_site ) ;
156
148
}
157
149
}
158
150
}
159
- fn check_pat ( & mut self , lcx : & LateContext < ' _ , ' _ > , pat : & hir:: Pat < ' _ > ) {
151
+ fn check_pat ( & mut self , cx : & LateContext < ' _ , ' _ > , pat : & hir:: Pat < ' _ > ) {
160
152
if in_macro ( pat. span ) {
161
153
let call_site = pat. span . source_callsite ( ) ;
162
- let name = snippet ( lcx , lcx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
154
+ let name = snippet ( cx , cx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
163
155
if let Some ( callee) = pat. span . source_callee ( ) {
164
- if !self . collected . contains ( & call_site) {
165
- self . mac_refs
166
- . push ( ( call_site, MacroRefData :: new ( & name, callee. def_site , lcx) ) ) ;
167
- self . collected . insert ( call_site) ;
168
- }
156
+ self . push_unique_macro_pat_ty ( cx, & name, call_site, callee. def_site ) ;
169
157
}
170
158
}
171
159
}
172
- fn check_ty ( & mut self , lcx : & LateContext < ' _ , ' _ > , ty : & hir:: Ty < ' _ > ) {
160
+ fn check_ty ( & mut self , cx : & LateContext < ' _ , ' _ > , ty : & hir:: Ty < ' _ > ) {
173
161
if in_macro ( ty. span ) {
174
162
let call_site = ty. span . source_callsite ( ) ;
175
- let name = snippet ( lcx , lcx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
163
+ let name = snippet ( cx , cx . sess ( ) . source_map ( ) . span_until_char ( call_site, '!' ) , "_" ) ;
176
164
if let Some ( callee) = ty. span . source_callee ( ) {
177
- if !self . collected . contains ( & call_site) {
178
- self . mac_refs
179
- . push ( ( call_site, MacroRefData :: new ( & name, callee. def_site , lcx) ) ) ;
180
- self . collected . insert ( call_site) ;
181
- }
165
+ self . push_unique_macro_pat_ty ( cx, & name, call_site, callee. def_site ) ;
182
166
}
183
167
}
184
168
}
185
169
186
- fn check_crate_post ( & mut self , lcx : & LateContext < ' _ , ' _ > , _krate : & hir:: Crate < ' _ > ) {
170
+ fn check_crate_post ( & mut self , cx : & LateContext < ' _ , ' _ > , _krate : & hir:: Crate < ' _ > ) {
187
171
for ( import, span) in & self . imports {
188
- let matched = self . mac_refs . iter ( ) . any ( |( _span , mac) | import. ends_with ( & mac. name ) ) ;
172
+ let matched = self . mac_refs . iter ( ) . any ( |mac| import. ends_with ( & mac. name ) ) ;
189
173
190
174
if matched {
191
- self . mac_refs . retain ( |( _span , mac) | !import. ends_with ( & mac. name ) ) ;
175
+ self . mac_refs . retain ( |mac| !import. ends_with ( & mac. name ) ) ;
192
176
let msg = "`macro_use` attributes are no longer needed in the Rust 2018 edition" ;
193
177
let help = format ! ( "use {}" , import) ;
194
178
span_lint_and_sugg (
195
- lcx ,
179
+ cx ,
196
180
MACRO_USE_IMPORTS ,
197
181
* span,
198
182
msg,
199
183
"remove the attribute and import the macro directly, try" ,
200
184
help,
201
- Applicability :: HasPlaceholders ,
185
+ Applicability :: MaybeIncorrect ,
202
186
)
203
187
}
204
188
}
0 commit comments