@@ -101,6 +101,15 @@ pub enum LegacyScope<'a> {
101
101
Invocation ( & ' a InvocationData < ' a > ) ,
102
102
}
103
103
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
+
104
113
pub struct ProcMacError {
105
114
crate_name : Symbol ,
106
115
name : Symbol ,
@@ -326,14 +335,15 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
326
335
InvocationKind :: Attr { attr : None , .. } =>
327
336
return Ok ( None ) ,
328
337
InvocationKind :: Attr { attr : Some ( ref attr) , ref traits, .. } =>
329
- ( & attr. path , MacroKind :: Attr , & traits[ .. ] ) ,
338
+ ( & attr. path , MacroKind :: Attr , traits. clone ( ) ) ,
330
339
InvocationKind :: Bang { ref mac, .. } =>
331
- ( & mac. node . path , MacroKind :: Bang , & [ ] [ .. ] ) ,
340
+ ( & mac. node . path , MacroKind :: Bang , Vec :: new ( ) ) ,
332
341
InvocationKind :: Derive { ref path, .. } =>
333
- ( path, MacroKind :: Derive , & [ ] [ .. ] ) ,
342
+ ( path, MacroKind :: Derive , Vec :: new ( ) ) ,
334
343
} ;
335
344
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) ?;
337
347
338
348
if let Def :: Macro ( def_id, _) = def {
339
349
self . macro_defs . insert ( invoc. expansion_data . mark , def_id) ;
@@ -349,9 +359,10 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
349
359
}
350
360
351
361
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 )
353
363
-> 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 )
355
366
}
356
367
357
368
fn check_unused_macros ( & self ) {
@@ -373,10 +384,28 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
373
384
}
374
385
375
386
impl < ' 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) ;
380
409
381
410
// Report errors and enforce feature gates for the resolved macro.
382
411
if def != Err ( Determinacy :: Undetermined ) {
@@ -440,15 +469,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
440
469
Ok ( ( def, self . get_macro ( def) ) )
441
470
}
442
471
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 > {
446
479
let ast:: Path { ref segments, span } = * path;
447
480
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 ( ) ;
452
481
453
482
// Possibly apply the macro helper hack
454
483
if kind == MacroKind :: Bang && path. len ( ) == 1 &&
@@ -458,9 +487,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
458
487
}
459
488
460
489
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 ) {
464
493
PathResult :: NonModule ( path_res) => match path_res. base_def ( ) {
465
494
Def :: Err => Err ( Determinacy :: Determined ) ,
466
495
def @ _ => {
@@ -480,19 +509,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
480
509
Err ( Determinacy :: Determined )
481
510
} ,
482
511
} ;
483
- self . current_module . macro_resolutions . borrow_mut ( )
512
+ parent_scope . module . macro_resolutions . borrow_mut ( )
484
513
. push ( ( path. into_boxed_slice ( ) , span) ) ;
485
514
return def;
486
515
}
487
516
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 ) {
492
519
Ok ( legacy_binding. def ( ) )
493
520
} else {
494
521
match self . resolve_lexical_macro_path_segment ( path[ 0 ] , MacroNS , Some ( kind) ,
495
- parent_expansion , false , force, span) {
522
+ parent_scope , false , force, span) {
496
523
Ok ( ( binding, _) ) => Ok ( binding. def_ignoring_ambiguity ( ) ) ,
497
524
Err ( Determinacy :: Undetermined ) => return Err ( Determinacy :: Undetermined ) ,
498
525
Err ( Determinacy :: Determined ) => {
@@ -502,8 +529,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
502
529
}
503
530
} ;
504
531
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 ( ) ) ) ;
507
534
508
535
if let Ok ( Def :: NonMacroAttr ( NonMacroAttrKind :: Custom ) ) = result { } else {
509
536
return result;
@@ -521,9 +548,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
521
548
assert ! ( kind == MacroKind :: Attr ) ;
522
549
enum ConvertToDeriveHelper { Yes , No , DontKnow }
523
550
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 {
527
554
if inert_attrs. contains ( & path[ 0 ] . name ) {
528
555
convert_to_derive_helper = ConvertToDeriveHelper :: Yes ;
529
556
break
@@ -551,7 +578,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
551
578
mut ident : Ident ,
552
579
ns : Namespace ,
553
580
kind : Option < MacroKind > ,
554
- parent_expansion : Mark ,
581
+ parent_scope : & ParentScope < ' a > ,
555
582
record_used : bool ,
556
583
force : bool ,
557
584
path_span : Span ,
@@ -610,8 +637,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
610
637
}
611
638
612
639
// 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 ;
615
642
loop {
616
643
let result = match where_to_resolve {
617
644
WhereToResolve :: Module ( module) => {
@@ -755,7 +782,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
755
782
// Found another solution, if the first one was "weak", report an error.
756
783
if result. 0 . def ( ) != innermost_result. 0 . def ( ) &&
757
784
( 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 ) ) {
759
786
self . ambiguity_errors . push ( AmbiguityError {
760
787
ident,
761
788
b1 : innermost_result. 0 ,
@@ -797,13 +824,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
797
824
}
798
825
}
799
826
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 > > {
807
834
if macro_kind_mismatch ( ident. name , kind, Some ( MacroKind :: Bang ) ) {
808
835
return None ;
809
836
}
@@ -824,7 +851,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
824
851
let mut innermost_result: Option < & NameBinding > = None ;
825
852
826
853
// 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 ;
828
855
loop {
829
856
let result = match where_to_resolve {
830
857
LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
@@ -852,7 +879,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
852
879
if let Some ( innermost_result) = innermost_result {
853
880
// Found another solution, if the first one was "weak", report an error.
854
881
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) {
856
883
self . ambiguity_errors . push ( AmbiguityError {
857
884
ident,
858
885
b1 : innermost_result,
@@ -889,14 +916,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
889
916
}
890
917
}
891
918
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 {
894
922
let span = ident. span ;
895
923
let legacy_resolution = self . resolve_legacy_scope (
896
- ident, Some ( kind) , parent_expansion , parent_legacy_scope , true
924
+ ident, Some ( kind) , & parent_scope , true
897
925
) ;
898
926
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
900
928
) ;
901
929
902
930
let check_consistency = |this : & Self , new_def : Def | {
@@ -932,7 +960,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
932
960
( Some ( legacy_binding) , Ok ( ( binding, FromPrelude ( from_prelude) ) ) )
933
961
if legacy_binding. def ( ) != binding. def_ignoring_ambiguity ( ) &&
934
962
( !from_prelude ||
935
- legacy_binding. may_appear_after ( parent_expansion , binding) ) => {
963
+ legacy_binding. may_appear_after ( parent_scope . expansion , binding) ) => {
936
964
self . report_ambiguity_error ( ident, legacy_binding, binding) ;
937
965
} ,
938
966
// OK, non-macro-expanded legacy wins over prelude even if defs are different
@@ -953,13 +981,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
953
981
} ;
954
982
}
955
983
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 {
958
986
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
960
988
) ;
961
989
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
963
991
) . map ( |( binding, _) | binding) . ok ( ) ;
964
992
965
993
if let Some ( binding) = resolve_legacy ( self ) . or_else ( || resolve_modern ( self ) ) {
0 commit comments