@@ -26,7 +26,6 @@ use Determinacy::*;
2626use rustc_arena:: { DroplessArena , TypedArena } ;
2727use rustc_ast:: node_id:: NodeMap ;
2828use rustc_ast:: ptr:: P ;
29- use rustc_ast:: unwrap_or;
3029use rustc_ast:: visit:: { self , Visitor } ;
3130use rustc_ast:: { self as ast, NodeId } ;
3231use rustc_ast:: { Crate , CRATE_NODE_ID } ;
@@ -43,7 +42,7 @@ use rustc_hir::def::Namespace::*;
4342use rustc_hir:: def:: { self , CtorOf , DefKind , NonMacroAttrKind , PartialRes } ;
4443use rustc_hir:: def_id:: { CrateNum , DefId , DefIdMap , LocalDefId , CRATE_DEF_INDEX } ;
4544use rustc_hir:: definitions:: { DefKey , DefPathData , Definitions } ;
46- use rustc_hir:: { PrimTy , TraitCandidate } ;
45+ use rustc_hir:: TraitCandidate ;
4746use rustc_index:: vec:: IndexVec ;
4847use rustc_metadata:: creader:: { CStore , CrateLoader } ;
4948use rustc_middle:: hir:: exports:: ExportMap ;
@@ -109,7 +108,9 @@ enum Scope<'a> {
109108 DeriveHelpersCompat ,
110109 MacroRules ( MacroRulesScopeRef < ' a > ) ,
111110 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 > ) ,
113114 RegisteredAttrs ,
114115 MacroUsePrelude ,
115116 BuiltinAttrs ,
@@ -123,13 +124,17 @@ enum Scope<'a> {
123124/// with different restrictions when looking up the resolution.
124125/// This enum is currently used only for early resolution (imports and macros),
125126/// but not for late resolution yet.
126- enum ScopeSet {
127+ #[ derive( Clone , Copy ) ]
128+ enum ScopeSet < ' a > {
127129 /// All scopes with the given namespace.
128130 All ( Namespace , /*is_import*/ bool ) ,
129131 /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros).
130132 AbsolutePath ( Namespace ) ,
131133 /// All scopes with macro namespace and the given macro kind restriction.
132134 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 > ) ,
133138}
134139
135140/// Everything you need to know about a name's location to resolve it.
@@ -1467,7 +1472,7 @@ impl<'a> Resolver<'a> {
14671472
14681473 self . visit_scopes ( ScopeSet :: All ( TypeNS , false ) , parent_scope, ctxt, |this, scope, _, _| {
14691474 match scope {
1470- Scope :: Module ( module) => {
1475+ Scope :: Module ( module, _ ) => {
14711476 this. traits_in_module ( module, assoc_item, & mut found_traits) ;
14721477 }
14731478 Scope :: StdLibPrelude => {
@@ -1631,7 +1636,7 @@ impl<'a> Resolver<'a> {
16311636 /// If the callback returns `Some` result, we stop visiting scopes and return it.
16321637 fn visit_scopes < T > (
16331638 & mut self ,
1634- scope_set : ScopeSet ,
1639+ scope_set : ScopeSet < ' a > ,
16351640 parent_scope : & ParentScope < ' a > ,
16361641 ctxt : SyntaxContext ,
16371642 mut visitor : impl FnMut (
@@ -1687,12 +1692,17 @@ impl<'a> Resolver<'a> {
16871692 ScopeSet :: All ( ns, _) => ( ns, None , false ) ,
16881693 ScopeSet :: AbsolutePath ( ns) => ( ns, None , true ) ,
16891694 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 ( ) ,
16901702 } ;
1691- // Jump out of trait or enum modules, they do not act as scopes.
1692- let module = parent_scope. module . nearest_item_scope ( ) ;
16931703 let mut scope = match ns {
16941704 _ if is_absolute_path => Scope :: CrateRoot ,
1695- TypeNS | ValueNS => Scope :: Module ( module) ,
1705+ TypeNS | ValueNS => Scope :: Module ( module, None ) ,
16961706 MacroNS => Scope :: DeriveHelpers ( parent_scope. expansion ) ,
16971707 } ;
16981708 let mut ctxt = ctxt. normalize_to_macros_2_0 ( ) ;
@@ -1757,7 +1767,7 @@ impl<'a> Resolver<'a> {
17571767 MacroRulesScope :: Invocation ( invoc_id) => {
17581768 Scope :: MacroRules ( self . invocation_parent_scopes [ & invoc_id] . macro_rules )
17591769 }
1760- MacroRulesScope :: Empty => Scope :: Module ( module) ,
1770+ MacroRulesScope :: Empty => Scope :: Module ( module, None ) ,
17611771 } ,
17621772 Scope :: CrateRoot => match ns {
17631773 TypeNS => {
@@ -1766,10 +1776,16 @@ impl<'a> Resolver<'a> {
17661776 }
17671777 ValueNS | MacroNS => break ,
17681778 } ,
1769- Scope :: Module ( module) => {
1779+ Scope :: Module ( module, prev_lint_id ) => {
17701780 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+ }
17731789 None => {
17741790 ctxt. adjust ( ExpnId :: root ( ) ) ;
17751791 match ns {
@@ -1825,6 +1841,7 @@ impl<'a> Resolver<'a> {
18251841 ribs : & [ Rib < ' a > ] ,
18261842 ) -> Option < LexicalScopeBinding < ' a > > {
18271843 assert ! ( ns == TypeNS || ns == ValueNS ) ;
1844+ let orig_ident = ident;
18281845 if ident. name == kw:: Empty {
18291846 return Some ( LexicalScopeBinding :: Res ( Res :: Err ) ) ;
18301847 }
@@ -1874,135 +1891,49 @@ impl<'a> Resolver<'a> {
18741891 _ => continue ,
18751892 } ;
18761893
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-
18901894 match module. kind {
18911895 ModuleKind :: Block ( ..) => { } // We can see through blocks
18921896 _ => break ,
18931897 }
1894- }
18951898
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 (
19141900 ModuleOrUniformRoot :: Module ( module) ,
19151901 ident,
19161902 ns,
1917- adjusted_parent_scope ,
1903+ parent_scope ,
19181904 record_used,
19191905 path_span,
19201906 ) ;
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.
19741909 return Some ( LexicalScopeBinding :: Item ( binding) ) ;
19751910 }
19761911 }
19771912
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 )
19791923 }
19801924
19811925 fn hygienic_lexical_parent (
19821926 & mut self ,
19831927 module : Module < ' a > ,
19841928 ctxt : & mut SyntaxContext ,
1985- ) -> Option < Module < ' a > > {
1929+ derive_fallback_lint_id : Option < NodeId > ,
1930+ ) -> Option < ( Module < ' a > , Option < NodeId > ) > {
19861931 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 ) ) ;
19881933 }
19891934
19901935 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 ) ) ;
20061937 }
20071938
20081939 // We need to support the next case under a deprecation warning
@@ -2016,20 +1947,21 @@ impl<'a> Resolver<'a> {
20161947 // ---- end
20171948 // ```
20181949 // 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+ }
20331965 }
20341966 }
20351967 }
0 commit comments