@@ -81,11 +81,29 @@ pub struct LegacyBinding<'a> {
81
81
pub span : Span ,
82
82
}
83
83
84
+ #[ derive( Copy , Clone ) ]
84
85
pub enum MacroBinding < ' a > {
85
86
Legacy ( & ' a LegacyBinding < ' a > ) ,
87
+ Global ( & ' a NameBinding < ' a > ) ,
86
88
Modern ( & ' a NameBinding < ' a > ) ,
87
89
}
88
90
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
+
89
107
impl < ' a > base:: Resolver for Resolver < ' a > {
90
108
fn next_node_id ( & mut self ) -> ast:: NodeId {
91
109
self . session . next_node_id ( )
@@ -171,7 +189,7 @@ impl<'a> base::Resolver for Resolver<'a> {
171
189
vis : ty:: Visibility :: Invisible ,
172
190
expansion : Mark :: root ( ) ,
173
191
} ) ;
174
- self . builtin_macros . insert ( ident. name , binding) ;
192
+ self . global_macros . insert ( ident. name , binding) ;
175
193
}
176
194
177
195
fn resolve_imports ( & mut self ) {
@@ -189,7 +207,7 @@ impl<'a> base::Resolver for Resolver<'a> {
189
207
attr:: mark_known ( & attrs[ i] ) ;
190
208
}
191
209
192
- match self . builtin_macros . get ( & name) . cloned ( ) {
210
+ match self . global_macros . get ( & name) . cloned ( ) {
193
211
Some ( binding) => match * binding. get_macro ( self ) {
194
212
MultiModifier ( ..) | MultiDecorator ( ..) | SyntaxExtension :: AttrProcMacro ( ..) => {
195
213
return Some ( attrs. remove ( i) )
@@ -221,7 +239,7 @@ impl<'a> base::Resolver for Resolver<'a> {
221
239
}
222
240
let trait_name = traits[ j] . segments [ 0 ] . identifier . name ;
223
241
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) {
225
243
continue
226
244
}
227
245
let span = traits. remove ( j) . span ;
@@ -378,18 +396,18 @@ impl<'a> Resolver<'a> {
378
396
}
379
397
380
398
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 ) ,
388
406
Err ( _) => {
389
407
self . found_unresolved_macro = true ;
390
408
Err ( Determinacy :: Determined )
391
409
}
392
- } ,
410
+ }
393
411
} ;
394
412
395
413
self . current_module . legacy_macro_resolutions . borrow_mut ( )
@@ -403,42 +421,56 @@ impl<'a> Resolver<'a> {
403
421
ident : Ident ,
404
422
ns : Namespace ,
405
423
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 } ;
409
429
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) {
413
442
Ok ( binding) => {
414
443
let span = match record_used {
415
444
Some ( span) => span,
416
- None => return Ok ( binding ) ,
445
+ None => return result ,
417
446
} ;
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 ( ) {
420
449
let name = ident. name ;
421
450
self . ambiguity_errors . push ( AmbiguityError {
422
451
span : span, name : name, b1 : shadower, b2 : binding, lexical : true ,
423
452
legacy : false ,
424
453
} ) ;
425
- return Ok ( shadower ) ;
454
+ return potential_illegal_shadower ;
426
455
}
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;
429
462
}
430
463
} ,
431
464
Err ( Determinacy :: Undetermined ) => return Err ( Determinacy :: Undetermined ) ,
432
465
Err ( Determinacy :: Determined ) => { }
433
466
}
434
467
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 ,
441
472
} ,
473
+ None => return potential_illegal_shadower,
442
474
}
443
475
}
444
476
}
@@ -488,11 +520,11 @@ impl<'a> Resolver<'a> {
488
520
489
521
let binding = if let Some ( binding) = binding {
490
522
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 ( ) {
492
524
if !self . use_extern_macros {
493
525
self . record_use ( Ident :: with_empty_ctxt ( name) , MacroNS , binding, DUMMY_SP ) ;
494
526
}
495
- MacroBinding :: Modern ( binding)
527
+ MacroBinding :: Global ( binding)
496
528
} else {
497
529
return None ;
498
530
} ;
@@ -524,21 +556,15 @@ impl<'a> Resolver<'a> {
524
556
let legacy_resolution = self . resolve_legacy_scope ( legacy_scope, ident. name , true ) ;
525
557
let resolution = self . resolve_lexical_macro_path_segment ( ident, MacroNS , Some ( span) ) ;
526
558
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) ;
535
561
let msg2 = format ! ( "`{}` could also refer to the macro imported here" , ident) ;
536
562
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)
539
565
. emit ( ) ;
540
566
} ,
541
- ( Some ( MacroBinding :: Modern ( binding) ) , Err ( _ ) ) => {
567
+ ( Some ( MacroBinding :: Global ( binding) ) , Ok ( MacroBinding :: Global ( _ ) ) ) => {
542
568
self . record_use ( ident, MacroNS , binding, span) ;
543
569
self . err_if_macro_use_proc_macro ( ident. name , span, binding) ;
544
570
} ,
@@ -567,11 +593,11 @@ impl<'a> Resolver<'a> {
567
593
find_best_match_for_name ( self . macro_names . iter ( ) , name, None )
568
594
} else {
569
595
None
570
- // Then check builtin macros.
596
+ // Then check global macros.
571
597
} . or_else ( || {
572
598
// 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) | {
575
601
if binding. get_macro ( self ) . kind ( ) == kind {
576
602
Some ( name)
577
603
} else {
0 commit comments