@@ -38,8 +38,8 @@ pub struct MacroRefData {
3838}
3939
4040impl 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 ( ) ;
4343
4444 // std lib paths are <::std::module::file type>
4545 // so remove brackets, space and type.
@@ -63,142 +63,126 @@ pub struct MacroUseImports {
6363 imports : Vec < ( String , Span ) > ,
6464 /// the span of the macro reference, kept to ensure only one reference is used per macro call.
6565 collected : FxHashSet < Span > ,
66- mac_refs : Vec < ( Span , MacroRefData ) > ,
66+ mac_refs : Vec < MacroRefData > ,
6767}
6868
6969impl_lint_pass ! ( MacroUseImports => [ MACRO_USE_IMPORTS ] ) ;
7070
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+
7193impl < ' 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 < ' _ > ) {
7395 if_chain ! {
74- if lcx . sess( ) . opts. edition == Edition :: Edition2018 ;
96+ if cx . sess( ) . opts. edition == Edition :: Edition2018 ;
7597 if let hir:: ItemKind :: Use ( path, _kind) = & item. kind;
7698 if let Some ( mac_attr) = item
7799 . attrs
78100 . iter( )
79101 . find( |attr| attr. ident( ) . map( |s| s. to_string( ) ) == Some ( "macro_use" . to_string( ) ) ) ;
80102 if let Res :: Def ( DefKind :: Mod , id) = path. res;
81103 then {
82- for kid in lcx . tcx. item_children( id) . iter( ) {
104+ for kid in cx . tcx. item_children( id) . iter( ) {
83105 if let Res :: Def ( DefKind :: Macro ( _mac_type) , mac_id) = kid. res {
84106 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) ) ;
86108 }
87109 }
88110 } 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+ }
96119 }
97120 }
98- }
99121 }
100122 }
101123 }
102- fn check_attribute ( & mut self , lcx : & LateContext < ' _ , ' _ > , attr : & ast:: Attribute ) {
124+ fn check_attribute ( & mut self , cx : & LateContext < ' _ , ' _ > , attr : & ast:: Attribute ) {
103125 if in_macro ( attr. span ) {
104126 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, '!' ) , "_" ) ;
106128 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 ) ;
118130 }
119131 }
120132 }
121- fn check_expr ( & mut self , lcx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr < ' _ > ) {
133+ fn check_expr ( & mut self , cx : & LateContext < ' _ , ' _ > , expr : & hir:: Expr < ' _ > ) {
122134 if in_macro ( expr. span ) {
123135 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, '!' ) , "_" ) ;
125137 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 ) ;
137139 }
138140 }
139141 }
140- fn check_stmt ( & mut self , lcx : & LateContext < ' _ , ' _ > , stmt : & hir:: Stmt < ' _ > ) {
142+ fn check_stmt ( & mut self , cx : & LateContext < ' _ , ' _ > , stmt : & hir:: Stmt < ' _ > ) {
141143 if in_macro ( stmt. span ) {
142144 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, '!' ) , "_" ) ;
144146 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 ) ;
156148 }
157149 }
158150 }
159- fn check_pat ( & mut self , lcx : & LateContext < ' _ , ' _ > , pat : & hir:: Pat < ' _ > ) {
151+ fn check_pat ( & mut self , cx : & LateContext < ' _ , ' _ > , pat : & hir:: Pat < ' _ > ) {
160152 if in_macro ( pat. span ) {
161153 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, '!' ) , "_" ) ;
163155 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 ) ;
169157 }
170158 }
171159 }
172- fn check_ty ( & mut self , lcx : & LateContext < ' _ , ' _ > , ty : & hir:: Ty < ' _ > ) {
160+ fn check_ty ( & mut self , cx : & LateContext < ' _ , ' _ > , ty : & hir:: Ty < ' _ > ) {
173161 if in_macro ( ty. span ) {
174162 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, '!' ) , "_" ) ;
176164 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 ) ;
182166 }
183167 }
184168 }
185169
186- fn check_crate_post ( & mut self , lcx : & LateContext < ' _ , ' _ > , _krate : & hir:: Crate < ' _ > ) {
170+ fn check_crate_post ( & mut self , cx : & LateContext < ' _ , ' _ > , _krate : & hir:: Crate < ' _ > ) {
187171 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 ) ) ;
189173
190174 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 ) ) ;
192176 let msg = "`macro_use` attributes are no longer needed in the Rust 2018 edition" ;
193177 let help = format ! ( "use {}" , import) ;
194178 span_lint_and_sugg (
195- lcx ,
179+ cx ,
196180 MACRO_USE_IMPORTS ,
197181 * span,
198182 msg,
199183 "remove the attribute and import the macro directly, try" ,
200184 help,
201- Applicability :: HasPlaceholders ,
185+ Applicability :: MaybeIncorrect ,
202186 )
203187 }
204188 }
0 commit comments