9
9
// except according to those terms.
10
10
11
11
use { AmbiguityError , AmbiguityKind , AmbiguityErrorMisc } ;
12
- use { CrateLint , Resolver , ResolutionError , is_known_tool, resolve_error} ;
12
+ use { CrateLint , DeterminacyExt , Resolver , ResolutionError , is_known_tool, resolve_error} ;
13
13
use { Module , ModuleKind , NameBinding , NameBindingKind , PathResult , ToNameBinding } ;
14
14
use ModuleOrUniformRoot ;
15
15
use Namespace :: { self , * } ;
@@ -54,8 +54,8 @@ pub struct InvocationData<'a> {
54
54
crate parent_legacy_scope : Cell < LegacyScope < ' a > > ,
55
55
/// Legacy scope *produced* by expanding this macro invocation,
56
56
/// includes all the macro_rules items, other invocations, etc generated by it.
57
- /// Set to the parent scope if the macro is not expanded yet (as if the macro produced nothing) .
58
- crate output_legacy_scope : Cell < LegacyScope < ' a > > ,
57
+ /// `None` if the macro is not expanded yet.
58
+ crate output_legacy_scope : Cell < Option < LegacyScope < ' a > > > ,
59
59
}
60
60
61
61
impl < ' a > InvocationData < ' a > {
@@ -64,7 +64,7 @@ impl<'a> InvocationData<'a> {
64
64
module : Cell :: new ( graph_root) ,
65
65
def_index : CRATE_DEF_INDEX ,
66
66
parent_legacy_scope : Cell :: new ( LegacyScope :: Empty ) ,
67
- output_legacy_scope : Cell :: new ( LegacyScope :: Empty ) ,
67
+ output_legacy_scope : Cell :: new ( Some ( LegacyScope :: Empty ) ) ,
68
68
}
69
69
}
70
70
}
@@ -110,7 +110,7 @@ pub struct ParentScope<'a> {
110
110
// Macro namespace is separated into two sub-namespaces, one for bang macros and
111
111
// one for attribute-like macros (attributes, derives).
112
112
// We ignore resolutions from one sub-namespace when searching names in scope for another.
113
- fn sub_namespace_mismatch ( requirement : Option < MacroKind > , candidate : Option < MacroKind > ) -> bool {
113
+ fn sub_namespace_match ( candidate : Option < MacroKind > , requirement : Option < MacroKind > ) -> bool {
114
114
#[ derive( PartialEq ) ]
115
115
enum SubNS { Bang , AttrLike }
116
116
let sub_ns = |kind| match kind {
@@ -121,7 +121,7 @@ fn sub_namespace_mismatch(requirement: Option<MacroKind>, candidate: Option<Macr
121
121
let requirement = requirement. and_then ( |kind| sub_ns ( kind) ) ;
122
122
let candidate = candidate. and_then ( |kind| sub_ns ( kind) ) ;
123
123
// "No specific sub-namespace" means "matches anything" for both requirements and candidates.
124
- candidate. is_some ( ) && requirement. is_some ( ) && candidate ! = requirement
124
+ candidate. is_none ( ) || requirement. is_none ( ) || candidate = = requirement
125
125
}
126
126
127
127
impl < ' a , ' crateloader : ' a > base:: Resolver for Resolver < ' a , ' crateloader > {
@@ -136,7 +136,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
136
136
module : Cell :: new ( module) ,
137
137
def_index : module. def_id ( ) . unwrap ( ) . index ,
138
138
parent_legacy_scope : Cell :: new ( LegacyScope :: Empty ) ,
139
- output_legacy_scope : Cell :: new ( LegacyScope :: Empty ) ,
139
+ output_legacy_scope : Cell :: new ( Some ( LegacyScope :: Empty ) ) ,
140
140
} ) ) ;
141
141
mark
142
142
}
@@ -212,7 +212,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
212
212
expansion : mark,
213
213
} ;
214
214
fragment. visit_with ( & mut visitor) ;
215
- invocation. output_legacy_scope . set ( visitor. current_legacy_scope ) ;
215
+ invocation. output_legacy_scope . set ( Some ( visitor. current_legacy_scope ) ) ;
216
216
}
217
217
218
218
fn add_builtin ( & mut self , ident : ast:: Ident , ext : Lrc < SyntaxExtension > ) {
@@ -620,38 +620,50 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
620
620
let mut innermost_result: Option < ( & NameBinding , Flags ) > = None ;
621
621
622
622
// Go through all the scopes and try to resolve the name.
623
- let mut where_to_resolve = WhereToResolve :: DeriveHelpers ;
623
+ let mut where_to_resolve = if ns == MacroNS {
624
+ WhereToResolve :: DeriveHelpers
625
+ } else {
626
+ WhereToResolve :: Module ( parent_scope. module )
627
+ } ;
624
628
let mut use_prelude = !parent_scope. module . no_implicit_prelude ;
629
+ let mut determinacy = Determinacy :: Determined ;
625
630
loop {
626
631
let result = match where_to_resolve {
627
632
WhereToResolve :: DeriveHelpers => {
628
633
let mut result = Err ( Determinacy :: Determined ) ;
629
634
for derive in & parent_scope. derives {
630
635
let parent_scope = ParentScope { derives : Vec :: new ( ) , ..* parent_scope } ;
631
- if let Ok ( ( _, ext) ) = self . resolve_macro_to_def ( derive, MacroKind :: Derive ,
632
- & parent_scope, force) {
633
- if let SyntaxExtension :: ProcMacroDerive ( _, helper_attrs, _) = & * ext {
634
- if helper_attrs. contains ( & ident. name ) {
635
- let binding =
636
- ( Def :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ,
637
- ty:: Visibility :: Public , derive. span , Mark :: root ( ) )
638
- . to_name_binding ( self . arenas ) ;
639
- result = Ok ( ( binding, Flags :: empty ( ) ) ) ;
640
- break ;
636
+ match self . resolve_macro_to_def ( derive, MacroKind :: Derive ,
637
+ & parent_scope, force) {
638
+ Ok ( ( _, ext) ) => {
639
+ if let SyntaxExtension :: ProcMacroDerive ( _, helpers, _) = & * ext {
640
+ if helpers. contains ( & ident. name ) {
641
+ let binding =
642
+ ( Def :: NonMacroAttr ( NonMacroAttrKind :: DeriveHelper ) ,
643
+ ty:: Visibility :: Public , derive. span , Mark :: root ( ) )
644
+ . to_name_binding ( self . arenas ) ;
645
+ result = Ok ( ( binding, Flags :: empty ( ) ) ) ;
646
+ break ;
647
+ }
641
648
}
642
649
}
650
+ Err ( Determinacy :: Determined ) => { }
651
+ Err ( Determinacy :: Undetermined ) =>
652
+ result = Err ( Determinacy :: Undetermined ) ,
643
653
}
644
654
}
645
655
result
646
656
}
647
657
WhereToResolve :: MacroRules ( legacy_scope) => match legacy_scope {
648
658
LegacyScope :: Binding ( legacy_binding) if ident == legacy_binding. ident =>
649
659
Ok ( ( legacy_binding. binding , Flags :: MACRO_RULES ) ) ,
660
+ LegacyScope :: Invocation ( invoc) if invoc. output_legacy_scope . get ( ) . is_none ( ) =>
661
+ Err ( Determinacy :: Undetermined ) ,
650
662
_ => Err ( Determinacy :: Determined ) ,
651
663
}
652
664
WhereToResolve :: Module ( module) => {
653
665
let orig_current_module = mem:: replace ( & mut self . current_module , module) ;
654
- let binding = self . resolve_ident_in_module_unadjusted (
666
+ let binding = self . resolve_ident_in_module_unadjusted_ext (
655
667
ModuleOrUniformRoot :: Module ( module) ,
656
668
ident,
657
669
ns,
@@ -660,17 +672,27 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
660
672
path_span,
661
673
) ;
662
674
self . current_module = orig_current_module;
663
- let misc_flags = if module. is_normal ( ) {
664
- Flags :: MISC_SUGGEST_SELF
665
- } else {
666
- Flags :: empty ( )
667
- } ;
668
- binding. map ( |binding| ( binding, Flags :: MODULE | misc_flags) )
675
+ match binding {
676
+ Ok ( binding) => {
677
+ let misc_flags = if module. is_normal ( ) {
678
+ Flags :: MISC_SUGGEST_SELF
679
+ } else {
680
+ Flags :: empty ( )
681
+ } ;
682
+ Ok ( ( binding, Flags :: MODULE | misc_flags) )
683
+ }
684
+ Err ( DeterminacyExt :: Undetermined ) =>
685
+ return Err ( Determinacy :: determined ( force) ) ,
686
+ Err ( DeterminacyExt :: WeakUndetermined ) => Err ( Determinacy :: Undetermined ) ,
687
+ Err ( DeterminacyExt :: Determined ) => Err ( Determinacy :: Determined ) ,
688
+ }
669
689
}
670
690
WhereToResolve :: MacroUsePrelude => {
671
691
match self . macro_use_prelude . get ( & ident. name ) . cloned ( ) {
672
692
Some ( binding) => Ok ( ( binding, Flags :: PRELUDE | Flags :: MISC_FROM_PRELUDE ) ) ,
673
- None => Err ( Determinacy :: Determined ) ,
693
+ None => Err ( Determinacy :: determined (
694
+ self . graph_root . unresolved_invocations . borrow ( ) . is_empty ( )
695
+ ) )
674
696
}
675
697
}
676
698
WhereToResolve :: BuiltinMacros => {
@@ -701,14 +723,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
701
723
}
702
724
}
703
725
WhereToResolve :: ExternPrelude => {
704
- let mut result = Err ( Determinacy :: Determined ) ;
705
726
if use_prelude {
706
- if let Some ( binding) = self . extern_prelude_get ( ident, !record_used,
707
- innermost_result. is_some ( ) ) {
708
- result = Ok ( ( binding, Flags :: PRELUDE ) ) ;
727
+ match self . extern_prelude_get ( ident, !record_used,
728
+ innermost_result. is_some ( ) ) {
729
+ Some ( binding) => Ok ( ( binding, Flags :: PRELUDE ) ) ,
730
+ None => Err ( Determinacy :: determined (
731
+ self . graph_root . unresolved_invocations . borrow ( ) . is_empty ( )
732
+ ) ) ,
709
733
}
734
+ } else {
735
+ Err ( Determinacy :: Determined )
710
736
}
711
- result
712
737
}
713
738
WhereToResolve :: ToolPrelude => {
714
739
if use_prelude && is_known_tool ( ident. name ) {
@@ -728,7 +753,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
728
753
ident,
729
754
ns,
730
755
false ,
731
- false ,
732
756
path_span,
733
757
) {
734
758
result = Ok ( ( binding, Flags :: PRELUDE | Flags :: MISC_FROM_PRELUDE ) ) ;
@@ -749,54 +773,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
749
773
}
750
774
} ;
751
775
752
- macro_rules! continue_search { ( ) => {
753
- where_to_resolve = match where_to_resolve {
754
- WhereToResolve :: DeriveHelpers =>
755
- WhereToResolve :: MacroRules ( parent_scope. legacy) ,
756
- WhereToResolve :: MacroRules ( legacy_scope) => match legacy_scope {
757
- LegacyScope :: Binding ( binding) =>
758
- WhereToResolve :: MacroRules ( binding. parent_legacy_scope) ,
759
- LegacyScope :: Invocation ( invocation) =>
760
- WhereToResolve :: MacroRules ( invocation. output_legacy_scope. get( ) ) ,
761
- LegacyScope :: Empty => WhereToResolve :: Module ( parent_scope. module) ,
762
- LegacyScope :: Uninitialized => unreachable!( ) ,
763
- }
764
- WhereToResolve :: Module ( module) => {
765
- match self . hygienic_lexical_parent( module, & mut ident. span) {
766
- Some ( parent_module) => WhereToResolve :: Module ( parent_module) ,
767
- None => {
768
- use_prelude = !module. no_implicit_prelude;
769
- match ns {
770
- TypeNS => WhereToResolve :: ExternPrelude ,
771
- ValueNS => WhereToResolve :: StdLibPrelude ,
772
- MacroNS => WhereToResolve :: MacroUsePrelude ,
773
- }
774
- }
775
- }
776
- }
777
- WhereToResolve :: MacroUsePrelude => WhereToResolve :: BuiltinMacros ,
778
- WhereToResolve :: BuiltinMacros => WhereToResolve :: BuiltinAttrs ,
779
- WhereToResolve :: BuiltinAttrs => WhereToResolve :: LegacyPluginHelpers ,
780
- WhereToResolve :: LegacyPluginHelpers => break , // nowhere else to search
781
- WhereToResolve :: ExternPrelude => WhereToResolve :: ToolPrelude ,
782
- WhereToResolve :: ToolPrelude => WhereToResolve :: StdLibPrelude ,
783
- WhereToResolve :: StdLibPrelude => match ns {
784
- TypeNS => WhereToResolve :: BuiltinTypes ,
785
- ValueNS => break , // nowhere else to search
786
- MacroNS => unreachable!( ) ,
787
- }
788
- WhereToResolve :: BuiltinTypes => break , // nowhere else to search
789
- } ;
790
-
791
- continue ;
792
- } }
793
-
794
776
match result {
795
- Ok ( ( binding, flags) ) => {
796
- if sub_namespace_mismatch ( macro_kind, binding. macro_kind ( ) ) {
797
- continue_search ! ( ) ;
798
- }
799
-
777
+ Ok ( ( binding, flags) ) if sub_namespace_match ( binding. macro_kind ( ) , macro_kind) => {
800
778
if !record_used {
801
779
return Ok ( binding) ;
802
780
}
@@ -857,22 +835,60 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
857
835
// Found the first solution.
858
836
innermost_result = Some ( ( binding, flags) ) ;
859
837
}
860
-
861
- continue_search ! ( ) ;
862
- } ,
863
- Err ( Determinacy :: Determined ) => {
864
- continue_search ! ( ) ;
865
838
}
866
- Err ( Determinacy :: Undetermined ) => return Err ( Determinacy :: determined ( force) ) ,
839
+ Ok ( ..) | Err ( Determinacy :: Determined ) => { }
840
+ Err ( Determinacy :: Undetermined ) => determinacy = Determinacy :: Undetermined
867
841
}
842
+
843
+ where_to_resolve = match where_to_resolve {
844
+ WhereToResolve :: DeriveHelpers =>
845
+ WhereToResolve :: MacroRules ( parent_scope. legacy ) ,
846
+ WhereToResolve :: MacroRules ( legacy_scope) => match legacy_scope {
847
+ LegacyScope :: Binding ( binding) => WhereToResolve :: MacroRules (
848
+ binding. parent_legacy_scope
849
+ ) ,
850
+ LegacyScope :: Invocation ( invoc) => WhereToResolve :: MacroRules (
851
+ invoc. output_legacy_scope . get ( ) . unwrap_or ( invoc. parent_legacy_scope . get ( ) )
852
+ ) ,
853
+ LegacyScope :: Empty => WhereToResolve :: Module ( parent_scope. module ) ,
854
+ LegacyScope :: Uninitialized => unreachable ! ( ) ,
855
+ }
856
+ WhereToResolve :: Module ( module) => {
857
+ match self . hygienic_lexical_parent ( module, & mut ident. span ) {
858
+ Some ( parent_module) => WhereToResolve :: Module ( parent_module) ,
859
+ None => {
860
+ use_prelude = !module. no_implicit_prelude ;
861
+ match ns {
862
+ TypeNS => WhereToResolve :: ExternPrelude ,
863
+ ValueNS => WhereToResolve :: StdLibPrelude ,
864
+ MacroNS => WhereToResolve :: MacroUsePrelude ,
865
+ }
866
+ }
867
+ }
868
+ }
869
+ WhereToResolve :: MacroUsePrelude => WhereToResolve :: BuiltinMacros ,
870
+ WhereToResolve :: BuiltinMacros => WhereToResolve :: BuiltinAttrs ,
871
+ WhereToResolve :: BuiltinAttrs => WhereToResolve :: LegacyPluginHelpers ,
872
+ WhereToResolve :: LegacyPluginHelpers => break , // nowhere else to search
873
+ WhereToResolve :: ExternPrelude => WhereToResolve :: ToolPrelude ,
874
+ WhereToResolve :: ToolPrelude => WhereToResolve :: StdLibPrelude ,
875
+ WhereToResolve :: StdLibPrelude => match ns {
876
+ TypeNS => WhereToResolve :: BuiltinTypes ,
877
+ ValueNS => break , // nowhere else to search
878
+ MacroNS => unreachable ! ( ) ,
879
+ }
880
+ WhereToResolve :: BuiltinTypes => break , // nowhere else to search
881
+ } ;
882
+
883
+ continue ;
868
884
}
869
885
870
886
// The first found solution was the only one, return it.
871
887
if let Some ( ( binding, ..) ) = innermost_result {
872
888
return Ok ( binding) ;
873
889
}
874
890
875
- let determinacy = Determinacy :: determined ( force) ;
891
+ let determinacy = Determinacy :: determined ( determinacy == Determinacy :: Determined || force) ;
876
892
if determinacy == Determinacy :: Determined && macro_kind == Some ( MacroKind :: Attr ) {
877
893
// For single-segment attributes interpret determinate "no resolution" as a custom
878
894
// attribute. (Lexical resolution implies the first segment and attr kind should imply
@@ -1016,7 +1032,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
1016
1032
def_index : invoc. def_index ,
1017
1033
module : Cell :: new ( graph_root) ,
1018
1034
parent_legacy_scope : Cell :: new ( LegacyScope :: Uninitialized ) ,
1019
- output_legacy_scope : Cell :: new ( LegacyScope :: Uninitialized ) ,
1035
+ output_legacy_scope : Cell :: new ( None ) ,
1020
1036
} )
1021
1037
} ) ;
1022
1038
} ;
0 commit comments