@@ -12,18 +12,28 @@ const PRELUDE: &[&str] = &[
1212 "marker" , "ops" , "convert" , "iter" , "option" , "result" , "borrow" , "boxed" , "string" , "vec" ,
1313 "macros"
1414] ;
15-
16- pub struct ImportData {
15+ const BRACKETS : & [ char ] = & [ '<' , '>' ] ;
16+ /// MacroRefData includes the name of the macro
17+ /// and the path from `SourceMap::span_to_filename`.
18+ pub struct MacroRefData {
1719 name : String ,
1820 path : String ,
1921}
2022
21- impl ImportData {
23+ impl MacroRefData {
2224 pub fn new ( name : String , span : Span , ecx : & EarlyContext < ' _ > ) -> Self {
23- let path = ecx. sess . source_map ( ) . span_to_filename ( span) ;
24- let path = ecx. sess . source_map ( ) . span_to_unmapped_path ( span) ;
25- println ! ( "NEW {:?} {:?}" , name, path) ;
26- Self { name : name. to_string ( ) , path : path. to_string ( ) , }
25+ let mut path = ecx. sess . source_map ( ) . span_to_filename ( span) . to_string ( ) ;
26+
27+ // std lib paths are <::std::module::file type>
28+ // so remove brackets and space
29+ if path. contains ( '<' ) {
30+ path = path. replace ( BRACKETS , "" ) ;
31+ }
32+ if path. contains ( ' ' ) {
33+ path = path. split ( ' ' ) . next ( ) . unwrap ( ) . to_string ( ) ;
34+ }
35+ println ! ( "NEW {} {}" , name, path) ;
36+ Self { name : name. to_string ( ) , path, }
2737 }
2838}
2939
@@ -47,17 +57,47 @@ declare_clippy_lint! {
4757
4858#[ derive( Default ) ]
4959pub struct MacroUseImport {
60+ /// the actual import path used and its span.
5061 imports : Vec < ( String , Span ) > ,
51- collected : FxHashMap < Span , ImportData > ,
62+ /// the span of the macro reference and the `MacroRefData`
63+ /// for the use of the macro.
64+ collected : FxHashMap < Span , MacroRefData > ,
5265}
5366
5467impl MacroUseImport {
55- fn import_path_mac ( & self , name : & str ) -> String {
56- println ! ( "END {:?}" , name) ;
57- String :: default ( )
68+ fn import_path_mac ( & self , use_path : & str ) -> String {
69+ println ! ( "END {:?}" , use_path) ;
70+
71+ for mac in self . collected . values ( ) {
72+ if paths_match ( mac, use_path) {
73+ return make_path ( mac, use_path)
74+ }
75+ }
76+ format ! ( "{}::<macro name>" , use_path)
5877 }
5978}
6079
80+ fn paths_match ( mac : & MacroRefData , use_path : & str ) -> bool {
81+ let segs = mac. path . split ( "::" )
82+ . filter ( |s| * s == "" )
83+ . collect :: < Vec < _ > > ( ) ;
84+ if segs. starts_with ( & [ "std" ] ) {
85+ return PRELUDE . iter ( ) . any ( |m| segs. contains ( m) )
86+ }
87+ false
88+ }
89+
90+ fn make_path ( mac : & MacroRefData , use_path : & str ) -> String {
91+ let mut res = String :: default ( ) ;
92+
93+ let segs = mac. path . split ( "::" )
94+ . filter ( |s| * s == "" )
95+ . collect :: < Vec < _ > > ( ) ;
96+
97+
98+ res
99+ }
100+
61101impl_lint_pass ! ( MacroUseImport => [ MACRO_USE_IMPORT ] ) ;
62102
63103impl EarlyLintPass for MacroUseImport {
@@ -85,7 +125,7 @@ impl EarlyLintPass for MacroUseImport {
85125 self . collected . entry ( call_site)
86126 . or_insert_with ( || {
87127 println ! ( "EXPR {:?}" , name) ;
88- ImportData :: new ( name. to_string ( ) , callee. def_site , ecx)
128+ MacroRefData :: new ( name. to_string ( ) , callee. def_site , ecx)
89129 } ) ;
90130 }
91131 }
@@ -98,7 +138,7 @@ impl EarlyLintPass for MacroUseImport {
98138 self . collected . entry ( call_site)
99139 . or_insert_with ( || {
100140 println ! ( "STMT {:?}" , name) ;
101- ImportData :: new ( name. to_string ( ) , callee. def_site , ecx)
141+ MacroRefData :: new ( name. to_string ( ) , callee. def_site , ecx)
102142 } ) ;
103143 }
104144 }
@@ -111,7 +151,7 @@ impl EarlyLintPass for MacroUseImport {
111151 self . collected . entry ( call_site)
112152 . or_insert_with ( || {
113153 println ! ( "PAT {:?}" , name) ;
114- ImportData :: new ( name. to_string ( ) , callee. def_site , ecx)
154+ MacroRefData :: new ( name. to_string ( ) , callee. def_site , ecx)
115155 } ) ;
116156 }
117157 }
@@ -123,15 +163,16 @@ impl EarlyLintPass for MacroUseImport {
123163 self . collected . entry ( call_site)
124164 . or_insert_with ( || {
125165 println ! ( "MAC {:?}" , name) ;
126- ImportData :: new ( name. to_string ( ) , callee. def_site , ecx)
166+ MacroRefData :: new ( name. to_string ( ) , callee. def_site , ecx)
127167 } ) ;
128168 }
129169 }
170+
130171 fn check_crate_post ( & mut self , ecx : & EarlyContext < ' _ > , krate : & ast:: Crate ) {
131172 for ( name, span) in self . imports . iter ( ) {
132173 let import_path = self . import_path_mac ( & name) ;
133174 let msg = "`macro_use` attributes are no longer needed in the Rust 2018 edition" ;
134- let help = format ! ( "use {}::{} " , import_path, name ) ;
175+ let help = format ! ( "use {}" , import_path) ;
135176 span_lint_and_sugg (
136177 ecx,
137178 MACRO_USE_IMPORT ,
0 commit comments