@@ -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+ Builtin ( & ' 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 :: Builtin ( binding) | MacroBinding :: Modern ( binding) => binding. span ,
96+ }
97+ }
98+
99+ pub fn binding ( self ) -> & ' a NameBinding < ' a > {
100+ match self {
101+ MacroBinding :: Builtin ( 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 ( )
@@ -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 builtin 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 . builtin_macros . get ( & ident. name ) . cloned ( ) . ok_or ( determinacy)
438+ . map ( MacroBinding :: Builtin )
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 }
@@ -492,7 +524,7 @@ impl<'a> Resolver<'a> {
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 :: Builtin ( 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 :: Builtin ( binding) ) , Ok ( MacroBinding :: Builtin ( _ ) ) ) => {
542568 self . record_use ( ident, MacroNS , binding, span) ;
543569 self . err_if_macro_use_proc_macro ( ident. name , span, binding) ;
544570 } ,
0 commit comments