@@ -23,7 +23,7 @@ use syntax::ast::{self, Name, Ident};
2323use syntax:: attr;
2424use syntax:: errors:: DiagnosticBuilder ;
2525use 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 } ;
2727use syntax:: ext:: base:: MacroKind ;
2828use syntax:: ext:: expand:: { Expansion , mark_tts} ;
2929use syntax:: ext:: hygiene:: Mark ;
@@ -152,16 +152,14 @@ impl<'a> base::Resolver for Resolver<'a> {
152152 }
153153
154154 fn add_ext ( & mut self , ident : ast:: Ident , ext : Rc < SyntaxExtension > ) {
155- if let NormalTT ( ..) = * ext {
156- self . macro_names . insert ( ident. name ) ;
157- }
158155 let def_id = DefId {
159156 krate : BUILTIN_MACROS_CRATE ,
160157 index : DefIndex :: new ( self . macro_map . len ( ) ) ,
161158 } ;
159+ let kind = ext. kind ( ) ;
162160 self . macro_map . insert ( def_id, ext) ;
163161 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 ) ) ,
165163 span : DUMMY_SP ,
166164 vis : ty:: Visibility :: Invisible ,
167165 expansion : Mark :: root ( ) ,
@@ -470,24 +468,40 @@ impl<'a> Resolver<'a> {
470468
471469 fn suggest_macro_name ( & mut self , name : & str , kind : MacroKind ,
472470 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 ;
489492 }
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+
491505 if let Some ( suggestion) = suggestion {
492506 if suggestion != name {
493507 if let MacroKind :: Bang = kind {
@@ -566,7 +580,7 @@ impl<'a> Resolver<'a> {
566580 } ) ;
567581 self . macro_exports . push ( Export {
568582 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 ) ,
570584 } ) ;
571585 self . exported_macros . push ( def) ;
572586 }
0 commit comments