@@ -23,7 +23,7 @@ use syntax::ast::{self, Name, Ident};
23
23
use syntax:: attr;
24
24
use syntax:: errors:: DiagnosticBuilder ;
25
25
use syntax:: ext:: base:: { self , Determinacy , MultiModifier , MultiDecorator } ;
26
- use syntax:: ext:: base:: { NormalTT , Resolver as SyntaxResolver , SyntaxExtension } ;
26
+ use syntax:: ext:: base:: { Resolver as SyntaxResolver , SyntaxExtension } ;
27
27
use syntax:: ext:: base:: MacroKind ;
28
28
use syntax:: ext:: expand:: { Expansion , mark_tts} ;
29
29
use syntax:: ext:: hygiene:: Mark ;
@@ -152,16 +152,14 @@ impl<'a> base::Resolver for Resolver<'a> {
152
152
}
153
153
154
154
fn add_ext ( & mut self , ident : ast:: Ident , ext : Rc < SyntaxExtension > ) {
155
- if let NormalTT ( ..) = * ext {
156
- self . macro_names . insert ( ident. name ) ;
157
- }
158
155
let def_id = DefId {
159
156
krate : BUILTIN_MACROS_CRATE ,
160
157
index : DefIndex :: new ( self . macro_map . len ( ) ) ,
161
158
} ;
159
+ let kind = ext. kind ( ) ;
162
160
self . macro_map . insert ( def_id, ext) ;
163
161
let binding = self . arenas . alloc_name_binding ( NameBinding {
164
- kind : NameBindingKind :: Def ( Def :: Macro ( def_id) ) ,
162
+ kind : NameBindingKind :: Def ( Def :: Macro ( def_id, kind ) ) ,
165
163
span : DUMMY_SP ,
166
164
vis : ty:: Visibility :: Invisible ,
167
165
expansion : Mark :: root ( ) ,
@@ -470,24 +468,40 @@ impl<'a> Resolver<'a> {
470
468
471
469
fn suggest_macro_name ( & mut self , name : & str , kind : MacroKind ,
472
470
err : & mut DiagnosticBuilder < ' a > ) {
473
- let suggestion = match kind {
474
- MacroKind :: Bang =>
475
- find_best_match_for_name ( self . macro_names . iter ( ) , name, None ) ,
476
- MacroKind :: Attr |
477
- MacroKind :: Derive => {
478
- // Find a suggestion from the legacy namespace.
479
- // FIXME: get_macro needs an &mut Resolver, can we do it without cloning?
480
- let builtin_macros = self . builtin_macros . clone ( ) ;
481
- let names = builtin_macros. iter ( ) . filter_map ( |( name, binding) | {
482
- if binding. get_macro ( self ) . kind ( ) == kind {
483
- Some ( name)
484
- } else {
485
- None
486
- }
487
- } ) ;
488
- find_best_match_for_name ( names, name, None )
471
+ // First check if this is a locally-defined bang macro.
472
+ let suggestion = if let MacroKind :: Bang = kind {
473
+ find_best_match_for_name ( self . macro_names . iter ( ) , name, None )
474
+ } else {
475
+ None
476
+ // Then check builtin macros.
477
+ } . or_else ( || {
478
+ // FIXME: get_macro needs an &mut Resolver, can we do it without cloning?
479
+ let builtin_macros = self . builtin_macros . clone ( ) ;
480
+ let names = builtin_macros. iter ( ) . filter_map ( |( name, binding) | {
481
+ if binding. get_macro ( self ) . kind ( ) == kind {
482
+ Some ( name)
483
+ } else {
484
+ None
485
+ }
486
+ } ) ;
487
+ find_best_match_for_name ( names, name, None )
488
+ // Then check modules.
489
+ } ) . or_else ( || {
490
+ if !self . use_extern_macros {
491
+ return None ;
489
492
}
490
- } ;
493
+ let is_macro = |def| {
494
+ if let Def :: Macro ( _, def_kind) = def {
495
+ def_kind == kind
496
+ } else {
497
+ false
498
+ }
499
+ } ;
500
+ let ident = Ident :: from_str ( name) ;
501
+ self . lookup_typo_candidate ( & vec ! [ ident] , MacroNS , is_macro)
502
+ . as_ref ( ) . map ( |s| Symbol :: intern ( s) )
503
+ } ) ;
504
+
491
505
if let Some ( suggestion) = suggestion {
492
506
if suggestion != name {
493
507
if let MacroKind :: Bang = kind {
@@ -566,7 +580,7 @@ impl<'a> Resolver<'a> {
566
580
} ) ;
567
581
self . macro_exports . push ( Export {
568
582
name : def. ident . name ,
569
- def : Def :: Macro ( self . definitions . local_def_id ( def. id ) ) ,
583
+ def : Def :: Macro ( self . definitions . local_def_id ( def. id ) , MacroKind :: Bang ) ,
570
584
} ) ;
571
585
self . exported_macros . push ( def) ;
572
586
}
0 commit comments