@@ -101,6 +101,15 @@ pub enum LegacyScope<'a> {
101101 Invocation ( & ' a InvocationData < ' a > ) ,
102102}
103103
104+ /// Everything you need to resolve a macro path.
105+ #[ derive( Clone ) ]
106+ pub struct ParentScope < ' a > {
107+ crate module : Module < ' a > ,
108+ crate expansion : Mark ,
109+ crate legacy : LegacyScope < ' a > ,
110+ crate derives : Vec < ast:: Path > ,
111+ }
112+
104113pub struct ProcMacError {
105114 crate_name : Symbol ,
106115 name : Symbol ,
@@ -326,14 +335,15 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
326335 InvocationKind :: Attr { attr : None , .. } =>
327336 return Ok ( None ) ,
328337 InvocationKind :: Attr { attr : Some ( ref attr) , ref traits, .. } =>
329- ( & attr. path , MacroKind :: Attr , & traits[ .. ] ) ,
338+ ( & attr. path , MacroKind :: Attr , traits. clone ( ) ) ,
330339 InvocationKind :: Bang { ref mac, .. } =>
331- ( & mac. node . path , MacroKind :: Bang , & [ ] [ .. ] ) ,
340+ ( & mac. node . path , MacroKind :: Bang , Vec :: new ( ) ) ,
332341 InvocationKind :: Derive { ref path, .. } =>
333- ( path, MacroKind :: Derive , & [ ] [ .. ] ) ,
342+ ( path, MacroKind :: Derive , Vec :: new ( ) ) ,
334343 } ;
335344
336- let ( def, ext) = self . resolve_macro_to_def ( path, kind, invoc_id, derives_in_scope, force) ?;
345+ let parent_scope = self . invoc_parent_scope ( invoc_id, derives_in_scope) ;
346+ let ( def, ext) = self . resolve_macro_to_def ( path, kind, & parent_scope, force) ?;
337347
338348 if let Def :: Macro ( def_id, _) = def {
339349 self . macro_defs . insert ( invoc. expansion_data . mark , def_id) ;
@@ -349,9 +359,10 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
349359 }
350360
351361 fn resolve_macro_path ( & mut self , path : & ast:: Path , kind : MacroKind , invoc_id : Mark ,
352- derives_in_scope : & [ ast:: Path ] , force : bool )
362+ derives_in_scope : Vec < ast:: Path > , force : bool )
353363 -> Result < Lrc < SyntaxExtension > , Determinacy > {
354- Ok ( self . resolve_macro_to_def ( path, kind, invoc_id, derives_in_scope, force) ?. 1 )
364+ let parent_scope = self . invoc_parent_scope ( invoc_id, derives_in_scope) ;
365+ Ok ( self . resolve_macro_to_def ( path, kind, & parent_scope, force) ?. 1 )
355366 }
356367
357368 fn check_unused_macros ( & self ) {
@@ -373,10 +384,28 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
373384}
374385
375386impl < ' a , ' cl > Resolver < ' a , ' cl > {
376- fn resolve_macro_to_def ( & mut self , path : & ast:: Path , kind : MacroKind , invoc_id : Mark ,
377- derives_in_scope : & [ ast:: Path ] , force : bool )
378- -> Result < ( Def , Lrc < SyntaxExtension > ) , Determinacy > {
379- let def = self . resolve_macro_to_def_inner ( path, kind, invoc_id, derives_in_scope, force) ;
387+ pub fn dummy_parent_scope ( & mut self ) -> ParentScope < ' a > {
388+ self . invoc_parent_scope ( Mark :: root ( ) , Vec :: new ( ) )
389+ }
390+
391+ fn invoc_parent_scope ( & mut self , invoc_id : Mark , derives : Vec < ast:: Path > ) -> ParentScope < ' a > {
392+ let invoc = self . invocations [ & invoc_id] ;
393+ ParentScope {
394+ module : invoc. module . get ( ) . nearest_item_scope ( ) ,
395+ expansion : invoc_id. parent ( ) ,
396+ legacy : invoc. parent_legacy_scope . get ( ) ,
397+ derives,
398+ }
399+ }
400+
401+ fn resolve_macro_to_def (
402+ & mut self ,
403+ path : & ast:: Path ,
404+ kind : MacroKind ,
405+ parent_scope : & ParentScope < ' a > ,
406+ force : bool ,
407+ ) -> Result < ( Def , Lrc < SyntaxExtension > ) , Determinacy > {
408+ let def = self . resolve_macro_to_def_inner ( path, kind, parent_scope, force) ;
380409
381410 // Report errors and enforce feature gates for the resolved macro.
382411 if def != Err ( Determinacy :: Undetermined ) {
@@ -440,15 +469,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
440469 Ok ( ( def, self . get_macro ( def) ) )
441470 }
442471
443- pub fn resolve_macro_to_def_inner ( & mut self , path : & ast:: Path , kind : MacroKind , invoc_id : Mark ,
444- derives_in_scope : & [ ast:: Path ] , force : bool )
445- -> Result < Def , Determinacy > {
472+ pub fn resolve_macro_to_def_inner (
473+ & mut self ,
474+ path : & ast:: Path ,
475+ kind : MacroKind ,
476+ parent_scope : & ParentScope < ' a > ,
477+ force : bool ,
478+ ) -> Result < Def , Determinacy > {
446479 let ast:: Path { ref segments, span } = * path;
447480 let mut path: Vec < _ > = segments. iter ( ) . map ( |seg| seg. ident ) . collect ( ) ;
448- let invocation = self . invocations [ & invoc_id] ;
449- let parent_expansion = invoc_id. parent ( ) ;
450- let parent_legacy_scope = invocation. parent_legacy_scope . get ( ) ;
451- self . current_module = invocation. module . get ( ) . nearest_item_scope ( ) ;
452481
453482 // Possibly apply the macro helper hack
454483 if kind == MacroKind :: Bang && path. len ( ) == 1 &&
@@ -458,9 +487,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
458487 }
459488
460489 if path. len ( ) > 1 {
461- let def = match self . resolve_path_with_parent_expansion ( None , & path, Some ( MacroNS ) ,
462- parent_expansion , false , span,
463- CrateLint :: No ) {
490+ let def = match self . resolve_path_with_parent_scope ( None , & path, Some ( MacroNS ) ,
491+ parent_scope , false , span,
492+ CrateLint :: No ) {
464493 PathResult :: NonModule ( path_res) => match path_res. base_def ( ) {
465494 Def :: Err => Err ( Determinacy :: Determined ) ,
466495 def @ _ => {
@@ -480,19 +509,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
480509 Err ( Determinacy :: Determined )
481510 } ,
482511 } ;
483- self . current_module . macro_resolutions . borrow_mut ( )
512+ parent_scope . module . macro_resolutions . borrow_mut ( )
484513 . push ( ( path. into_boxed_slice ( ) , span) ) ;
485514 return def;
486515 }
487516
488- let legacy_resolution = self . resolve_legacy_scope (
489- path[ 0 ] , Some ( kind) , parent_expansion, parent_legacy_scope, false
490- ) ;
491- let result = if let Some ( legacy_binding) = legacy_resolution {
517+ let result = if let Some ( legacy_binding) = self . resolve_legacy_scope ( path[ 0 ] , Some ( kind) ,
518+ parent_scope, false ) {
492519 Ok ( legacy_binding. def ( ) )
493520 } else {
494521 match self . resolve_lexical_macro_path_segment ( path[ 0 ] , MacroNS , Some ( kind) ,
495- parent_expansion , false , force, span) {
522+ parent_scope , false , force, span) {
496523 Ok ( ( binding, _) ) => Ok ( binding. def_ignoring_ambiguity ( ) ) ,
497524 Err ( Determinacy :: Undetermined ) => return Err ( Determinacy :: Undetermined ) ,
498525 Err ( Determinacy :: Determined ) => {
@@ -502,8 +529,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
502529 }
503530 } ;
504531
505- self . current_module . legacy_macro_resolutions . borrow_mut ( )
506- . push ( ( path[ 0 ] , kind, parent_expansion , parent_legacy_scope , result. ok ( ) ) ) ;
532+ parent_scope . module . legacy_macro_resolutions . borrow_mut ( )
533+ . push ( ( path[ 0 ] , kind, parent_scope . clone ( ) , result. ok ( ) ) ) ;
507534
508535 if let Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: Custom ) ) = result { } else {
509536 return result;
@@ -521,9 +548,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
521548 assert ! ( kind == MacroKind :: Attr ) ;
522549 enum ConvertToDeriveHelper { Yes , No , DontKnow }
523550 let mut convert_to_derive_helper = ConvertToDeriveHelper :: No ;
524- for derive in derives_in_scope {
525- match self . resolve_macro_path ( derive, MacroKind :: Derive , invoc_id , & [ ] , force) {
526- Ok ( ext) => if let SyntaxExtension :: ProcMacroDerive ( _, ref inert_attrs, _) = * ext {
551+ for derive in & parent_scope . derives {
552+ match self . resolve_macro_to_def ( derive, MacroKind :: Derive , parent_scope , force) {
553+ Ok ( ( _ , ext) ) => if let SyntaxExtension :: ProcMacroDerive ( _, inert_attrs, _) = & * ext {
527554 if inert_attrs. contains ( & path[ 0 ] . name ) {
528555 convert_to_derive_helper = ConvertToDeriveHelper :: Yes ;
529556 break
@@ -551,7 +578,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
551578 mut ident : Ident ,
552579 ns : Namespace ,
553580 kind : Option < MacroKind > ,
554- parent_expansion : Mark ,
581+ parent_scope : & ParentScope < ' a > ,
555582 record_used : bool ,
556583 force : bool ,
557584 path_span : Span ,
@@ -610,8 +637,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
610637 }
611638
612639 // Go through all the scopes and try to resolve the name.
613- let mut where_to_resolve = WhereToResolve :: Module ( self . current_module ) ;
614- let mut use_prelude = !self . current_module . no_implicit_prelude ;
640+ let mut where_to_resolve = WhereToResolve :: Module ( parent_scope . module ) ;
641+ let mut use_prelude = !parent_scope . module . no_implicit_prelude ;
615642 loop {
616643 let result = match where_to_resolve {
617644 WhereToResolve :: Module ( module) => {
@@ -755,7 +782,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
755782 // Found another solution, if the first one was "weak", report an error.
756783 if result. 0 . def ( ) != innermost_result. 0 . def ( ) &&
757784 ( innermost_result. 0 . is_glob_import ( ) ||
758- innermost_result. 0 . may_appear_after ( parent_expansion , result. 0 ) ) {
785+ innermost_result. 0 . may_appear_after ( parent_scope . expansion , result. 0 ) ) {
759786 self . ambiguity_errors . push ( AmbiguityError {
760787 ident,
761788 b1 : innermost_result. 0 ,
@@ -797,13 +824,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
797824 }
798825 }
799826
800- fn resolve_legacy_scope ( & mut self ,
801- ident : Ident ,
802- kind : Option < MacroKind > ,
803- parent_expansion : Mark ,
804- parent_legacy_scope : LegacyScope < ' a > ,
805- record_used : bool )
806- -> Option < & ' a NameBinding < ' a > > {
827+ fn resolve_legacy_scope (
828+ & mut self ,
829+ ident : Ident ,
830+ kind : Option < MacroKind > ,
831+ parent_scope : & ParentScope < ' a > ,
832+ record_used : bool ,
833+ ) -> Option < & ' a NameBinding < ' a > > {
807834 if macro_kind_mismatch ( ident. name , kind, Some ( MacroKind :: Bang ) ) {
808835 return None ;
809836 }
@@ -824,7 +851,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
824851 let mut innermost_result: Option < & NameBinding > = None ;
825852
826853 // Go through all the scopes and try to resolve the name.
827- let mut where_to_resolve = parent_legacy_scope ;
854+ let mut where_to_resolve = parent_scope . legacy ;
828855 loop {
829856 let result = match where_to_resolve {
830857 LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
@@ -852,7 +879,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
852879 if let Some ( innermost_result) = innermost_result {
853880 // Found another solution, if the first one was "weak", report an error.
854881 if result. def ( ) != innermost_result. def ( ) &&
855- innermost_result. may_appear_after ( parent_expansion , result) {
882+ innermost_result. may_appear_after ( parent_scope . expansion , result) {
856883 self . ambiguity_errors . push ( AmbiguityError {
857884 ident,
858885 b1 : innermost_result,
@@ -889,14 +916,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
889916 }
890917 }
891918
892- for & ( ident, kind, parent_expansion, parent_legacy_scope, def)
893- in module. legacy_macro_resolutions . borrow ( ) . iter ( ) {
919+ let legacy_macro_resolutions =
920+ mem:: replace ( & mut * module. legacy_macro_resolutions . borrow_mut ( ) , Vec :: new ( ) ) ;
921+ for ( ident, kind, parent_scope, def) in legacy_macro_resolutions {
894922 let span = ident. span ;
895923 let legacy_resolution = self . resolve_legacy_scope (
896- ident, Some ( kind) , parent_expansion , parent_legacy_scope , true
924+ ident, Some ( kind) , & parent_scope , true
897925 ) ;
898926 let resolution = self . resolve_lexical_macro_path_segment (
899- ident, MacroNS , Some ( kind) , parent_expansion , true , true , span
927+ ident, MacroNS , Some ( kind) , & parent_scope , true , true , span
900928 ) ;
901929
902930 let check_consistency = |this : & Self , new_def : Def | {
@@ -932,7 +960,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
932960 ( Some ( legacy_binding) , Ok ( ( binding, FromPrelude ( from_prelude) ) ) )
933961 if legacy_binding. def ( ) != binding. def_ignoring_ambiguity ( ) &&
934962 ( !from_prelude ||
935- legacy_binding. may_appear_after ( parent_expansion , binding) ) => {
963+ legacy_binding. may_appear_after ( parent_scope . expansion , binding) ) => {
936964 self . report_ambiguity_error ( ident, legacy_binding, binding) ;
937965 } ,
938966 // OK, non-macro-expanded legacy wins over prelude even if defs are different
@@ -953,13 +981,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
953981 } ;
954982 }
955983
956- for & ( ident , parent_expansion , parent_legacy_scope )
957- in module . builtin_attrs . borrow ( ) . iter ( ) {
984+ let builtin_attrs = mem :: replace ( & mut * module . builtin_attrs . borrow_mut ( ) , Vec :: new ( ) ) ;
985+ for ( ident , parent_scope ) in builtin_attrs {
958986 let resolve_legacy = |this : & mut Self | this. resolve_legacy_scope (
959- ident, Some ( MacroKind :: Attr ) , parent_expansion , parent_legacy_scope , true
987+ ident, Some ( MacroKind :: Attr ) , & parent_scope , true
960988 ) ;
961989 let resolve_modern = |this : & mut Self | this. resolve_lexical_macro_path_segment (
962- ident, MacroNS , Some ( MacroKind :: Attr ) , parent_expansion , true , true , ident. span
990+ ident, MacroNS , Some ( MacroKind :: Attr ) , & parent_scope , true , true , ident. span
963991 ) . map ( |( binding, _) | binding) . ok ( ) ;
964992
965993 if let Some ( binding) = resolve_legacy ( self ) . or_else ( || resolve_modern ( self ) ) {
0 commit comments