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