@@ -81,11 +81,29 @@ pub struct LegacyBinding<'a> {
8181 pub span : Span ,
8282}
8383
84+ #[ derive( Copy , Clone ) ]
8485pub enum MacroBinding < ' a > {
8586 Legacy ( & ' a LegacyBinding < ' a > ) ,
87+ Global ( & ' a NameBinding < ' a > ) ,
8688 Modern ( & ' a NameBinding < ' a > ) ,
8789}
8890
91+ impl < ' a > MacroBinding < ' a > {
92+ pub fn span ( self ) -> Span {
93+ match self {
94+ MacroBinding :: Legacy ( binding) => binding. span ,
95+ MacroBinding :: Global ( binding) | MacroBinding :: Modern ( binding) => binding. span ,
96+ }
97+ }
98+
99+ pub fn binding ( self ) -> & ' a NameBinding < ' a > {
100+ match self {
101+ MacroBinding :: Global ( binding) | MacroBinding :: Modern ( binding) => binding,
102+ MacroBinding :: Legacy ( _) => panic ! ( "unexpected MacroBinding::Legacy" ) ,
103+ }
104+ }
105+ }
106+
89107impl < ' a > base:: Resolver for Resolver < ' a > {
90108 fn next_node_id ( & mut self ) -> ast:: NodeId {
91109 self . session . next_node_id ( )
@@ -171,7 +189,7 @@ impl<'a> base::Resolver for Resolver<'a> {
171189 vis : ty:: Visibility :: Invisible ,
172190 expansion : Mark :: root ( ) ,
173191 } ) ;
174- self . builtin_macros . insert ( ident. name , binding) ;
192+ self . global_macros . insert ( ident. name , binding) ;
175193 }
176194
177195 fn resolve_imports ( & mut self ) {
@@ -189,7 +207,7 @@ impl<'a> base::Resolver for Resolver<'a> {
189207 attr:: mark_known ( & attrs[ i] ) ;
190208 }
191209
192- match self . builtin_macros . get ( & name) . cloned ( ) {
210+ match self . global_macros . get ( & name) . cloned ( ) {
193211 Some ( binding) => match * binding. get_macro ( self ) {
194212 MultiModifier ( ..) | MultiDecorator ( ..) | SyntaxExtension :: AttrProcMacro ( ..) => {
195213 return Some ( attrs. remove ( i) )
@@ -221,7 +239,7 @@ impl<'a> base::Resolver for Resolver<'a> {
221239 }
222240 let trait_name = traits[ j] . segments [ 0 ] . identifier . name ;
223241 let legacy_name = Symbol :: intern ( & format ! ( "derive_{}" , trait_name) ) ;
224- if !self . builtin_macros . contains_key ( & legacy_name) {
242+ if !self . global_macros . contains_key ( & legacy_name) {
225243 continue
226244 }
227245 let span = traits. remove ( j) . span ;
@@ -378,18 +396,18 @@ impl<'a> Resolver<'a> {
378396 }
379397
380398 let name = path[ 0 ] . name ;
381- let result = match self . resolve_legacy_scope ( & invocation. legacy_scope , name, false ) {
382- Some ( MacroBinding :: Legacy ( binding) ) => Ok ( Def :: Macro ( binding . def_id , MacroKind :: Bang ) ) ,
383- Some ( MacroBinding :: Modern ( binding) ) => Ok ( binding . def_ignoring_ambiguity ( ) ) ,
384- None => match self . resolve_lexical_macro_path_segment ( path [ 0 ] , MacroNS , None ) {
385- Ok ( binding ) => Ok ( binding . def_ignoring_ambiguity ( ) ) ,
386- Err ( Determinacy :: Undetermined ) if !force =>
387- return Err ( Determinacy :: Undetermined ) ,
399+ let legacy_resolution = self . resolve_legacy_scope ( & invocation. legacy_scope , name, false ) ;
400+ let result = if let Some ( MacroBinding :: Legacy ( binding) ) = legacy_resolution {
401+ Ok ( Def :: Macro ( binding. def_id , MacroKind :: Bang ) )
402+ } else {
403+ match self . resolve_lexical_macro_path_segment ( path [ 0 ] , MacroNS , None ) {
404+ Ok ( binding ) => Ok ( binding . binding ( ) . def_ignoring_ambiguity ( ) ) ,
405+ Err ( Determinacy :: Undetermined ) if !force => return Err ( Determinacy :: Undetermined ) ,
388406 Err ( _) => {
389407 self . found_unresolved_macro = true ;
390408 Err ( Determinacy :: Determined )
391409 }
392- } ,
410+ }
393411 } ;
394412
395413 self . current_module . legacy_macro_resolutions . borrow_mut ( )
@@ -403,42 +421,56 @@ impl<'a> Resolver<'a> {
403421 ident : Ident ,
404422 ns : Namespace ,
405423 record_used : Option < Span > )
406- -> Result < & ' a NameBinding < ' a > , Determinacy > {
407- let mut module = self . current_module ;
408- let mut potential_expanded_shadower: Option < & NameBinding > = None ;
424+ -> Result < MacroBinding < ' a > , Determinacy > {
425+ let mut module = Some ( self . current_module ) ;
426+ let mut potential_illegal_shadower = Err ( Determinacy :: Determined ) ;
427+ let determinacy =
428+ if record_used. is_some ( ) { Determinacy :: Determined } else { Determinacy :: Undetermined } ;
409429 loop {
410- // Since expanded macros may not shadow the lexical scope (enforced below),
411- // we can ignore unresolved invocations (indicated by the penultimate argument).
412- match self . resolve_ident_in_module ( module, ident, ns, true , record_used) {
430+ let result = if let Some ( module) = module {
431+ // Since expanded macros may not shadow the lexical scope and
432+ // globs may not shadow global macros (both enforced below),
433+ // we resolve with restricted shadowing (indicated by the penultimate argument).
434+ self . resolve_ident_in_module ( module, ident, ns, true , record_used)
435+ . map ( MacroBinding :: Modern )
436+ } else {
437+ self . global_macros . get ( & ident. name ) . cloned ( ) . ok_or ( determinacy)
438+ . map ( MacroBinding :: Global )
439+ } ;
440+
441+ match result. map ( MacroBinding :: binding) {
413442 Ok ( binding) => {
414443 let span = match record_used {
415444 Some ( span) => span,
416- None => return Ok ( binding ) ,
445+ None => return result ,
417446 } ;
418- match potential_expanded_shadower {
419- Some ( shadower ) if shadower. def ( ) != binding. def ( ) => {
447+ if let Ok ( MacroBinding :: Modern ( shadower ) ) = potential_illegal_shadower {
448+ if shadower. def ( ) != binding. def ( ) {
420449 let name = ident. name ;
421450 self . ambiguity_errors . push ( AmbiguityError {
422451 span : span, name : name, b1 : shadower, b2 : binding, lexical : true ,
423452 legacy : false ,
424453 } ) ;
425- return Ok ( shadower ) ;
454+ return potential_illegal_shadower ;
426455 }
427- _ if binding. expansion == Mark :: root ( ) => return Ok ( binding) ,
428- _ => potential_expanded_shadower = Some ( binding) ,
456+ }
457+ if binding. expansion != Mark :: root ( ) ||
458+ ( binding. is_glob_import ( ) && module. unwrap ( ) . def ( ) . is_some ( ) ) {
459+ potential_illegal_shadower = result;
460+ } else {
461+ return result;
429462 }
430463 } ,
431464 Err ( Determinacy :: Undetermined ) => return Err ( Determinacy :: Undetermined ) ,
432465 Err ( Determinacy :: Determined ) => { }
433466 }
434467
435- match module. kind {
436- ModuleKind :: Block ( ..) => module = module. parent . unwrap ( ) ,
437- ModuleKind :: Def ( ..) => return match potential_expanded_shadower {
438- Some ( binding) => Ok ( binding) ,
439- None if record_used. is_some ( ) => Err ( Determinacy :: Determined ) ,
440- None => Err ( Determinacy :: Undetermined ) ,
468+ module = match module {
469+ Some ( module) => match module. kind {
470+ ModuleKind :: Block ( ..) => module. parent ,
471+ ModuleKind :: Def ( ..) => None ,
441472 } ,
473+ None => return potential_illegal_shadower,
442474 }
443475 }
444476 }
@@ -488,11 +520,11 @@ impl<'a> Resolver<'a> {
488520
489521 let binding = if let Some ( binding) = binding {
490522 MacroBinding :: Legacy ( binding)
491- } else if let Some ( binding) = self . builtin_macros . get ( & name) . cloned ( ) {
523+ } else if let Some ( binding) = self . global_macros . get ( & name) . cloned ( ) {
492524 if !self . use_extern_macros {
493525 self . record_use ( Ident :: with_empty_ctxt ( name) , MacroNS , binding, DUMMY_SP ) ;
494526 }
495- MacroBinding :: Modern ( binding)
527+ MacroBinding :: Global ( binding)
496528 } else {
497529 return None ;
498530 } ;
@@ -524,21 +556,15 @@ impl<'a> Resolver<'a> {
524556 let legacy_resolution = self . resolve_legacy_scope ( legacy_scope, ident. name , true ) ;
525557 let resolution = self . resolve_lexical_macro_path_segment ( ident, MacroNS , Some ( span) ) ;
526558 match ( legacy_resolution, resolution) {
527- ( Some ( legacy_resolution) , Ok ( resolution) ) => {
528- let ( legacy_span, participle) = match legacy_resolution {
529- MacroBinding :: Modern ( binding)
530- if binding. def ( ) == resolution. def ( ) => continue ,
531- MacroBinding :: Modern ( binding) => ( binding. span , "imported" ) ,
532- MacroBinding :: Legacy ( binding) => ( binding. span , "defined" ) ,
533- } ;
534- let msg1 = format ! ( "`{}` could refer to the macro {} here" , ident, participle) ;
559+ ( Some ( MacroBinding :: Legacy ( legacy_binding) ) , Ok ( MacroBinding :: Modern ( binding) ) ) => {
560+ let msg1 = format ! ( "`{}` could refer to the macro defined here" , ident) ;
535561 let msg2 = format ! ( "`{}` could also refer to the macro imported here" , ident) ;
536562 self . session . struct_span_err ( span, & format ! ( "`{}` is ambiguous" , ident) )
537- . span_note ( legacy_span , & msg1)
538- . span_note ( resolution . span , & msg2)
563+ . span_note ( legacy_binding . span , & msg1)
564+ . span_note ( binding . span , & msg2)
539565 . emit ( ) ;
540566 } ,
541- ( Some ( MacroBinding :: Modern ( binding) ) , Err ( _ ) ) => {
567+ ( Some ( MacroBinding :: Global ( binding) ) , Ok ( MacroBinding :: Global ( _ ) ) ) => {
542568 self . record_use ( ident, MacroNS , binding, span) ;
543569 self . err_if_macro_use_proc_macro ( ident. name , span, binding) ;
544570 } ,
@@ -567,11 +593,11 @@ impl<'a> Resolver<'a> {
567593 find_best_match_for_name ( self . macro_names . iter ( ) , name, None )
568594 } else {
569595 None
570- // Then check builtin macros.
596+ // Then check global macros.
571597 } . or_else ( || {
572598 // FIXME: get_macro needs an &mut Resolver, can we do it without cloning?
573- let builtin_macros = self . builtin_macros . clone ( ) ;
574- let names = builtin_macros . iter ( ) . filter_map ( |( name, binding) | {
599+ let global_macros = self . global_macros . clone ( ) ;
600+ let names = global_macros . iter ( ) . filter_map ( |( name, binding) | {
575601 if binding. get_macro ( self ) . kind ( ) == kind {
576602 Some ( name)
577603 } else {
0 commit comments