@@ -25,7 +25,6 @@ use Determinacy::*;
2525use rustc_arena:: { DroplessArena , TypedArena } ;
2626use rustc_ast:: node_id:: NodeMap ;
2727use rustc_ast:: ptr:: P ;
28- use rustc_ast:: unwrap_or;
2928use rustc_ast:: visit:: { self , Visitor } ;
3029use rustc_ast:: { self as ast, NodeId } ;
3130use rustc_ast:: { Crate , CRATE_NODE_ID } ;
@@ -42,7 +41,7 @@ use rustc_hir::def::Namespace::*;
4241use rustc_hir:: def:: { self , CtorOf , DefKind , NonMacroAttrKind , PartialRes } ;
4342use rustc_hir:: def_id:: { CrateNum , DefId , DefIdMap , LocalDefId , CRATE_DEF_INDEX } ;
4443use rustc_hir:: definitions:: { DefKey , DefPathData , Definitions } ;
45- use rustc_hir:: { PrimTy , TraitCandidate } ;
44+ use rustc_hir:: TraitCandidate ;
4645use rustc_index:: vec:: IndexVec ;
4746use rustc_metadata:: creader:: { CStore , CrateLoader } ;
4847use rustc_middle:: hir:: exports:: ExportMap ;
@@ -108,7 +107,9 @@ enum Scope<'a> {
108107 DeriveHelpersCompat ,
109108 MacroRules ( MacroRulesScopeRef < ' a > ) ,
110109 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 > ) ,
112113 RegisteredAttrs ,
113114 MacroUsePrelude ,
114115 BuiltinAttrs ,
@@ -122,13 +123,17 @@ enum Scope<'a> {
122123/// with different restrictions when looking up the resolution.
123124/// This enum is currently used only for early resolution (imports and macros),
124125/// but not for late resolution yet.
125- enum ScopeSet {
126+ #[ derive( Clone , Copy ) ]
127+ enum ScopeSet < ' a > {
126128 /// All scopes with the given namespace.
127129 All ( Namespace , /*is_import*/ bool ) ,
128130 /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros).
129131 AbsolutePath ( Namespace ) ,
130132 /// All scopes with macro namespace and the given macro kind restriction.
131133 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 > ) ,
132137}
133138
134139/// Everything you need to know about a name's location to resolve it.
@@ -1466,7 +1471,7 @@ impl<'a> Resolver<'a> {
14661471
14671472 self . visit_scopes ( ScopeSet :: All ( TypeNS , false ) , parent_scope, ctxt, |this, scope, _, _| {
14681473 match scope {
1469- Scope :: Module ( module) => {
1474+ Scope :: Module ( module, _ ) => {
14701475 this. traits_in_module ( module, assoc_item, & mut found_traits) ;
14711476 }
14721477 Scope :: StdLibPrelude => {
@@ -1630,7 +1635,7 @@ impl<'a> Resolver<'a> {
16301635 /// If the callback returns `Some` result, we stop visiting scopes and return it.
16311636 fn visit_scopes < T > (
16321637 & mut self ,
1633- scope_set : ScopeSet ,
1638+ scope_set : ScopeSet < ' a > ,
16341639 parent_scope : & ParentScope < ' a > ,
16351640 ctxt : SyntaxContext ,
16361641 mut visitor : impl FnMut (
@@ -1686,12 +1691,17 @@ impl<'a> Resolver<'a> {
16861691 ScopeSet :: All ( ns, _) => ( ns, None , false ) ,
16871692 ScopeSet :: AbsolutePath ( ns) => ( ns, None , true ) ,
16881693 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 ( ) ,
16891701 } ;
1690- // Jump out of trait or enum modules, they do not act as scopes.
1691- let module = parent_scope. module . nearest_item_scope ( ) ;
16921702 let mut scope = match ns {
16931703 _ if is_absolute_path => Scope :: CrateRoot ,
1694- TypeNS | ValueNS => Scope :: Module ( module) ,
1704+ TypeNS | ValueNS => Scope :: Module ( module, None ) ,
16951705 MacroNS => Scope :: DeriveHelpers ( parent_scope. expansion ) ,
16961706 } ;
16971707 let mut ctxt = ctxt. normalize_to_macros_2_0 ( ) ;
@@ -1756,7 +1766,7 @@ impl<'a> Resolver<'a> {
17561766 MacroRulesScope :: Invocation ( invoc_id) => {
17571767 Scope :: MacroRules ( self . invocation_parent_scopes [ & invoc_id] . macro_rules )
17581768 }
1759- MacroRulesScope :: Empty => Scope :: Module ( module) ,
1769+ MacroRulesScope :: Empty => Scope :: Module ( module, None ) ,
17601770 } ,
17611771 Scope :: CrateRoot => match ns {
17621772 TypeNS => {
@@ -1765,10 +1775,16 @@ impl<'a> Resolver<'a> {
17651775 }
17661776 ValueNS | MacroNS => break ,
17671777 } ,
1768- Scope :: Module ( module) => {
1778+ Scope :: Module ( module, prev_lint_id ) => {
17691779 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+ }
17721788 None => {
17731789 ctxt. adjust ( ExpnId :: root ( ) ) ;
17741790 match ns {
@@ -1824,6 +1840,7 @@ impl<'a> Resolver<'a> {
18241840 ribs : & [ Rib < ' a > ] ,
18251841 ) -> Option < LexicalScopeBinding < ' a > > {
18261842 assert ! ( ns == TypeNS || ns == ValueNS ) ;
1843+ let orig_ident = ident;
18271844 if ident. name == kw:: Empty {
18281845 return Some ( LexicalScopeBinding :: Res ( Res :: Err ) ) ;
18291846 }
@@ -1873,135 +1890,49 @@ impl<'a> Resolver<'a> {
18731890 _ => continue ,
18741891 } ;
18751892
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-
18891893 match module. kind {
18901894 ModuleKind :: Block ( ..) => { } // We can see through blocks
18911895 _ => break ,
18921896 }
1893- }
18941897
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 (
19131899 ModuleOrUniformRoot :: Module ( module) ,
19141900 ident,
19151901 ns,
1916- adjusted_parent_scope ,
1902+ parent_scope ,
19171903 record_used,
19181904 path_span,
19191905 ) ;
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.
19731908 return Some ( LexicalScopeBinding :: Item ( binding) ) ;
19741909 }
19751910 }
19761911
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 )
19781922 }
19791923
19801924 fn hygienic_lexical_parent (
19811925 & mut self ,
19821926 module : Module < ' a > ,
19831927 ctxt : & mut SyntaxContext ,
1984- ) -> Option < Module < ' a > > {
1928+ derive_fallback_lint_id : Option < NodeId > ,
1929+ ) -> Option < ( Module < ' a > , Option < NodeId > ) > {
19851930 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 ) ) ;
19871932 }
19881933
19891934 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 ) ) ;
20051936 }
20061937
20071938 // We need to support the next case under a deprecation warning
@@ -2015,20 +1946,21 @@ impl<'a> Resolver<'a> {
20151946 // ---- end
20161947 // ```
20171948 // 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+ }
20321964 }
20331965 }
20341966 }
0 commit comments