@@ -26,7 +26,6 @@ use Determinacy::*;
26
26
use rustc_arena:: { DroplessArena , TypedArena } ;
27
27
use rustc_ast:: node_id:: NodeMap ;
28
28
use rustc_ast:: ptr:: P ;
29
- use rustc_ast:: unwrap_or;
30
29
use rustc_ast:: visit:: { self , Visitor } ;
31
30
use rustc_ast:: { self as ast, NodeId } ;
32
31
use rustc_ast:: { Crate , CRATE_NODE_ID } ;
@@ -43,7 +42,7 @@ use rustc_hir::def::Namespace::*;
43
42
use rustc_hir:: def:: { self , CtorOf , DefKind , NonMacroAttrKind , PartialRes } ;
44
43
use rustc_hir:: def_id:: { CrateNum , DefId , DefIdMap , LocalDefId , CRATE_DEF_INDEX } ;
45
44
use rustc_hir:: definitions:: { DefKey , DefPathData , Definitions } ;
46
- use rustc_hir:: { PrimTy , TraitCandidate } ;
45
+ use rustc_hir:: TraitCandidate ;
47
46
use rustc_index:: vec:: IndexVec ;
48
47
use rustc_metadata:: creader:: { CStore , CrateLoader } ;
49
48
use rustc_middle:: hir:: exports:: ExportMap ;
@@ -109,7 +108,9 @@ enum Scope<'a> {
109
108
DeriveHelpersCompat ,
110
109
MacroRules ( MacroRulesScopeRef < ' a > ) ,
111
110
CrateRoot ,
112
- Module ( Module < ' a > ) ,
111
+ // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
112
+ // lint if it should be reported.
113
+ Module ( Module < ' a > , Option < NodeId > ) ,
113
114
RegisteredAttrs ,
114
115
MacroUsePrelude ,
115
116
BuiltinAttrs ,
@@ -123,13 +124,17 @@ enum Scope<'a> {
123
124
/// with different restrictions when looking up the resolution.
124
125
/// This enum is currently used only for early resolution (imports and macros),
125
126
/// but not for late resolution yet.
126
- enum ScopeSet {
127
+ #[ derive( Clone , Copy ) ]
128
+ enum ScopeSet < ' a > {
127
129
/// All scopes with the given namespace.
128
130
All ( Namespace , /*is_import*/ bool ) ,
129
131
/// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros).
130
132
AbsolutePath ( Namespace ) ,
131
133
/// All scopes with macro namespace and the given macro kind restriction.
132
134
Macro ( MacroKind ) ,
135
+ /// All scopes with the given namespace, used for partially performing late resolution.
136
+ /// The node id enables lints and is used for reporting them.
137
+ Late ( Namespace , Module < ' a > , Option < NodeId > ) ,
133
138
}
134
139
135
140
/// Everything you need to know about a name's location to resolve it.
@@ -1467,7 +1472,7 @@ impl<'a> Resolver<'a> {
1467
1472
1468
1473
self . visit_scopes ( ScopeSet :: All ( TypeNS , false ) , parent_scope, ctxt, |this, scope, _, _| {
1469
1474
match scope {
1470
- Scope :: Module ( module) => {
1475
+ Scope :: Module ( module, _ ) => {
1471
1476
this. traits_in_module ( module, assoc_item, & mut found_traits) ;
1472
1477
}
1473
1478
Scope :: StdLibPrelude => {
@@ -1631,7 +1636,7 @@ impl<'a> Resolver<'a> {
1631
1636
/// If the callback returns `Some` result, we stop visiting scopes and return it.
1632
1637
fn visit_scopes < T > (
1633
1638
& mut self ,
1634
- scope_set : ScopeSet ,
1639
+ scope_set : ScopeSet < ' a > ,
1635
1640
parent_scope : & ParentScope < ' a > ,
1636
1641
ctxt : SyntaxContext ,
1637
1642
mut visitor : impl FnMut (
@@ -1687,12 +1692,17 @@ impl<'a> Resolver<'a> {
1687
1692
ScopeSet :: All ( ns, _) => ( ns, None , false ) ,
1688
1693
ScopeSet :: AbsolutePath ( ns) => ( ns, None , true ) ,
1689
1694
ScopeSet :: Macro ( macro_kind) => ( MacroNS , Some ( macro_kind) , false ) ,
1695
+ ScopeSet :: Late ( ns, ..) => ( ns, None , false ) ,
1696
+ } ;
1697
+ let module = match scope_set {
1698
+ // Start with the specified module.
1699
+ ScopeSet :: Late ( _, module, _) => module,
1700
+ // Jump out of trait or enum modules, they do not act as scopes.
1701
+ _ => parent_scope. module . nearest_item_scope ( ) ,
1690
1702
} ;
1691
- // Jump out of trait or enum modules, they do not act as scopes.
1692
- let module = parent_scope. module . nearest_item_scope ( ) ;
1693
1703
let mut scope = match ns {
1694
1704
_ if is_absolute_path => Scope :: CrateRoot ,
1695
- TypeNS | ValueNS => Scope :: Module ( module) ,
1705
+ TypeNS | ValueNS => Scope :: Module ( module, None ) ,
1696
1706
MacroNS => Scope :: DeriveHelpers ( parent_scope. expansion ) ,
1697
1707
} ;
1698
1708
let mut ctxt = ctxt. normalize_to_macros_2_0 ( ) ;
@@ -1757,7 +1767,7 @@ impl<'a> Resolver<'a> {
1757
1767
MacroRulesScope :: Invocation ( invoc_id) => {
1758
1768
Scope :: MacroRules ( self . invocation_parent_scopes [ & invoc_id] . macro_rules )
1759
1769
}
1760
- MacroRulesScope :: Empty => Scope :: Module ( module) ,
1770
+ MacroRulesScope :: Empty => Scope :: Module ( module, None ) ,
1761
1771
} ,
1762
1772
Scope :: CrateRoot => match ns {
1763
1773
TypeNS => {
@@ -1766,10 +1776,16 @@ impl<'a> Resolver<'a> {
1766
1776
}
1767
1777
ValueNS | MacroNS => break ,
1768
1778
} ,
1769
- Scope :: Module ( module) => {
1779
+ Scope :: Module ( module, prev_lint_id ) => {
1770
1780
use_prelude = !module. no_implicit_prelude ;
1771
- match self . hygienic_lexical_parent ( module, & mut ctxt) {
1772
- Some ( parent_module) => Scope :: Module ( parent_module) ,
1781
+ let derive_fallback_lint_id = match scope_set {
1782
+ ScopeSet :: Late ( .., lint_id) => lint_id,
1783
+ _ => None ,
1784
+ } ;
1785
+ match self . hygienic_lexical_parent ( module, & mut ctxt, derive_fallback_lint_id) {
1786
+ Some ( ( parent_module, lint_id) ) => {
1787
+ Scope :: Module ( parent_module, lint_id. or ( prev_lint_id) )
1788
+ }
1773
1789
None => {
1774
1790
ctxt. adjust ( ExpnId :: root ( ) ) ;
1775
1791
match ns {
@@ -1825,6 +1841,7 @@ impl<'a> Resolver<'a> {
1825
1841
ribs : & [ Rib < ' a > ] ,
1826
1842
) -> Option < LexicalScopeBinding < ' a > > {
1827
1843
assert ! ( ns == TypeNS || ns == ValueNS ) ;
1844
+ let orig_ident = ident;
1828
1845
if ident. name == kw:: Empty {
1829
1846
return Some ( LexicalScopeBinding :: Res ( Res :: Err ) ) ;
1830
1847
}
@@ -1874,135 +1891,49 @@ impl<'a> Resolver<'a> {
1874
1891
_ => continue ,
1875
1892
} ;
1876
1893
1877
- let item = self . resolve_ident_in_module_unadjusted (
1878
- ModuleOrUniformRoot :: Module ( module) ,
1879
- ident,
1880
- ns,
1881
- parent_scope,
1882
- record_used,
1883
- path_span,
1884
- ) ;
1885
- if let Ok ( binding) = item {
1886
- // The ident resolves to an item.
1887
- return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1888
- }
1889
-
1890
1894
match module. kind {
1891
1895
ModuleKind :: Block ( ..) => { } // We can see through blocks
1892
1896
_ => break ,
1893
1897
}
1894
- }
1895
1898
1896
- ident = normalized_ident;
1897
- let mut poisoned = None ;
1898
- loop {
1899
- let mut span_data = ident. span . data ( ) ;
1900
- let opt_module = if let Some ( node_id) = record_used_id {
1901
- self . hygienic_lexical_parent_with_compatibility_fallback (
1902
- module,
1903
- & mut span_data. ctxt ,
1904
- node_id,
1905
- & mut poisoned,
1906
- )
1907
- } else {
1908
- self . hygienic_lexical_parent ( module, & mut span_data. ctxt )
1909
- } ;
1910
- ident. span = span_data. span ( ) ;
1911
- module = unwrap_or ! ( opt_module, break ) ;
1912
- let adjusted_parent_scope = & ParentScope { module, ..* parent_scope } ;
1913
- let result = self . resolve_ident_in_module_unadjusted (
1899
+ let item = self . resolve_ident_in_module_unadjusted (
1914
1900
ModuleOrUniformRoot :: Module ( module) ,
1915
1901
ident,
1916
1902
ns,
1917
- adjusted_parent_scope ,
1903
+ parent_scope ,
1918
1904
record_used,
1919
1905
path_span,
1920
1906
) ;
1921
-
1922
- match result {
1923
- Ok ( binding) => {
1924
- if let Some ( node_id) = poisoned {
1925
- self . lint_buffer . buffer_lint_with_diagnostic (
1926
- lint:: builtin:: PROC_MACRO_DERIVE_RESOLUTION_FALLBACK ,
1927
- node_id,
1928
- ident. span ,
1929
- & format ! ( "cannot find {} `{}` in this scope" , ns. descr( ) , ident) ,
1930
- BuiltinLintDiagnostics :: ProcMacroDeriveResolutionFallback ( ident. span ) ,
1931
- ) ;
1932
- }
1933
- return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1934
- }
1935
- Err ( Determined ) => continue ,
1936
- Err ( Undetermined ) => {
1937
- span_bug ! ( ident. span, "undetermined resolution during main resolution pass" )
1938
- }
1939
- }
1940
- }
1941
-
1942
- if !module. no_implicit_prelude {
1943
- ident. span . adjust ( ExpnId :: root ( ) ) ;
1944
- if ns == TypeNS {
1945
- if let Some ( binding) = self . extern_prelude_get ( ident, !record_used) {
1946
- return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1947
- }
1948
- if let Some ( ident) = self . registered_tools . get ( & ident) {
1949
- let binding =
1950
- ( Res :: ToolMod , ty:: Visibility :: Public , ident. span , ExpnId :: root ( ) )
1951
- . to_name_binding ( self . arenas ) ;
1952
- return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1953
- }
1954
- }
1955
- if let Some ( prelude) = self . prelude {
1956
- if let Ok ( binding) = self . resolve_ident_in_module_unadjusted (
1957
- ModuleOrUniformRoot :: Module ( prelude) ,
1958
- ident,
1959
- ns,
1960
- parent_scope,
1961
- false ,
1962
- path_span,
1963
- ) {
1964
- return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1965
- }
1966
- }
1967
- }
1968
-
1969
- if ns == TypeNS {
1970
- if let Some ( prim_ty) = PrimTy :: from_name ( ident. name ) {
1971
- let binding =
1972
- ( Res :: PrimTy ( prim_ty) , ty:: Visibility :: Public , DUMMY_SP , ExpnId :: root ( ) )
1973
- . to_name_binding ( self . arenas ) ;
1907
+ if let Ok ( binding) = item {
1908
+ // The ident resolves to an item.
1974
1909
return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1975
1910
}
1976
1911
}
1977
1912
1978
- None
1913
+ self . early_resolve_ident_in_lexical_scope (
1914
+ orig_ident,
1915
+ ScopeSet :: Late ( ns, module, record_used_id) ,
1916
+ parent_scope,
1917
+ record_used,
1918
+ record_used,
1919
+ path_span,
1920
+ )
1921
+ . ok ( )
1922
+ . map ( LexicalScopeBinding :: Item )
1979
1923
}
1980
1924
1981
1925
fn hygienic_lexical_parent (
1982
1926
& mut self ,
1983
1927
module : Module < ' a > ,
1984
1928
ctxt : & mut SyntaxContext ,
1985
- ) -> Option < Module < ' a > > {
1929
+ derive_fallback_lint_id : Option < NodeId > ,
1930
+ ) -> Option < ( Module < ' a > , Option < NodeId > ) > {
1986
1931
if !module. expansion . outer_expn_is_descendant_of ( * ctxt) {
1987
- return Some ( self . macro_def_scope ( ctxt. remove_mark ( ) ) ) ;
1932
+ return Some ( ( self . macro_def_scope ( ctxt. remove_mark ( ) ) , None ) ) ;
1988
1933
}
1989
1934
1990
1935
if let ModuleKind :: Block ( ..) = module. kind {
1991
- return Some ( module. parent . unwrap ( ) . nearest_item_scope ( ) ) ;
1992
- }
1993
-
1994
- None
1995
- }
1996
-
1997
- fn hygienic_lexical_parent_with_compatibility_fallback (
1998
- & mut self ,
1999
- module : Module < ' a > ,
2000
- ctxt : & mut SyntaxContext ,
2001
- node_id : NodeId ,
2002
- poisoned : & mut Option < NodeId > ,
2003
- ) -> Option < Module < ' a > > {
2004
- if let module @ Some ( ..) = self . hygienic_lexical_parent ( module, ctxt) {
2005
- return module;
1936
+ return Some ( ( module. parent . unwrap ( ) . nearest_item_scope ( ) , None ) ) ;
2006
1937
}
2007
1938
2008
1939
// We need to support the next case under a deprecation warning
@@ -2016,20 +1947,21 @@ impl<'a> Resolver<'a> {
2016
1947
// ---- end
2017
1948
// ```
2018
1949
// So we have to fall back to the module's parent during lexical resolution in this case.
2019
- if let Some ( parent) = module. parent {
2020
- // Inner module is inside the macro, parent module is outside of the macro.
2021
- if module. expansion != parent. expansion
2022
- && module. expansion . is_descendant_of ( parent. expansion )
2023
- {
2024
- // The macro is a proc macro derive
2025
- if let Some ( def_id) = module. expansion . expn_data ( ) . macro_def_id {
2026
- let ext = self . get_macro_by_def_id ( def_id) ;
2027
- if ext. builtin_name . is_none ( )
2028
- && ext. macro_kind ( ) == MacroKind :: Derive
2029
- && parent. expansion . outer_expn_is_descendant_of ( * ctxt)
2030
- {
2031
- * poisoned = Some ( node_id) ;
2032
- return module. parent ;
1950
+ if derive_fallback_lint_id. is_some ( ) {
1951
+ if let Some ( parent) = module. parent {
1952
+ // Inner module is inside the macro, parent module is outside of the macro.
1953
+ if module. expansion != parent. expansion
1954
+ && module. expansion . is_descendant_of ( parent. expansion )
1955
+ {
1956
+ // The macro is a proc macro derive
1957
+ if let Some ( def_id) = module. expansion . expn_data ( ) . macro_def_id {
1958
+ let ext = self . get_macro_by_def_id ( def_id) ;
1959
+ if ext. builtin_name . is_none ( )
1960
+ && ext. macro_kind ( ) == MacroKind :: Derive
1961
+ && parent. expansion . outer_expn_is_descendant_of ( * ctxt)
1962
+ {
1963
+ return Some ( ( parent, derive_fallback_lint_id) ) ;
1964
+ }
2033
1965
}
2034
1966
}
2035
1967
}
0 commit comments