diff options
Diffstat (limited to 'compiler/rustc_resolve/src/ident.rs')
| -rw-r--r-- | compiler/rustc_resolve/src/ident.rs | 77 |
1 files changed, 43 insertions, 34 deletions
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 9efcef695b7..7ab932d9f2a 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -2,7 +2,7 @@ use Determinacy::*; use Namespace::*; use rustc_ast::{self as ast, NodeId}; use rustc_errors::ErrorGuaranteed; -use rustc_hir::def::{DefKind, Namespace, NonMacroAttrKind, PartialRes, PerNS}; +use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS}; use rustc_middle::bug; use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK; @@ -102,6 +102,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) | ScopeSet::Late(ns, ..) => (ns, None), + ScopeSet::ExternPrelude => (TypeNS, None), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), }; let module = match scope_set { @@ -111,8 +112,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { _ => parent_scope.module.nearest_item_scope(), }; let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)); + let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude); let mut scope = match ns { _ if module_and_extern_prelude => Scope::Module(module, None), + _ if extern_prelude => Scope::ExternPreludeItems, TypeNS | ValueNS => Scope::Module(module, None), MacroNS => Scope::DeriveHelpers(parent_scope.expansion), }; @@ -143,7 +146,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Scope::Module(..) => true, Scope::MacroUsePrelude => use_prelude || rust_2015, Scope::BuiltinAttrs => true, - Scope::ExternPrelude => use_prelude || module_and_extern_prelude, + Scope::ExternPreludeItems | Scope::ExternPreludeFlags => { + use_prelude || module_and_extern_prelude || extern_prelude + } Scope::ToolPrelude => use_prelude, Scope::StdLibPrelude => use_prelude || ns == MacroNS, Scope::BuiltinTypes => true, @@ -182,7 +187,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Scope::Module(..) if module_and_extern_prelude => match ns { TypeNS => { ctxt.adjust(ExpnId::root()); - Scope::ExternPrelude + Scope::ExternPreludeItems } ValueNS | MacroNS => break, }, @@ -199,7 +204,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { None => { ctxt.adjust(ExpnId::root()); match ns { - TypeNS => Scope::ExternPrelude, + TypeNS => Scope::ExternPreludeItems, ValueNS => Scope::StdLibPrelude, MacroNS => Scope::MacroUsePrelude, } @@ -208,8 +213,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } Scope::MacroUsePrelude => Scope::StdLibPrelude, Scope::BuiltinAttrs => break, // nowhere else to search - Scope::ExternPrelude if module_and_extern_prelude => break, - Scope::ExternPrelude => Scope::ToolPrelude, + Scope::ExternPreludeItems => Scope::ExternPreludeFlags, + Scope::ExternPreludeFlags if module_and_extern_prelude || extern_prelude => break, + Scope::ExternPreludeFlags => Scope::ToolPrelude, Scope::ToolPrelude => Scope::StdLibPrelude, Scope::StdLibPrelude => match ns { TypeNS => Scope::BuiltinTypes, @@ -259,7 +265,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { { let ext = &self.get_macro_by_def_id(def_id).ext; if ext.builtin_name.is_none() - && ext.macro_kind() == MacroKind::Derive + && ext.macro_kinds() == MacroKinds::DERIVE && parent.expansion.outer_expn_is_descendant_of(*ctxt) { return Some((parent, derive_fallback_lint_id)); @@ -413,6 +419,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) | ScopeSet::Late(ns, ..) => (ns, None), + ScopeSet::ExternPrelude => (TypeNS, None), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), }; @@ -429,6 +436,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // to detect potential ambiguities. let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None; let mut determinacy = Determinacy::Determined; + // Shadowed bindings don't need to be marked as used or non-speculatively loaded. + macro finalize_scope() { + if innermost_result.is_none() { finalize } else { None } + } // Go through all the scopes and try to resolve the name. let break_result = self.visit_scopes( @@ -494,7 +505,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { _ => Err(Determinacy::Determined), }, Scope::Module(module, derive_fallback_lint_id) => { - let (adjusted_parent_scope, finalize) = + // FIXME: use `finalize_scope` here. + let (adjusted_parent_scope, adjusted_finalize) = if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) { (parent_scope, finalize) } else { @@ -513,7 +525,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } else { Shadowing::Restricted }, - finalize, + adjusted_finalize, ignore_binding, ignore_import, ); @@ -561,14 +573,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Some(binding) => Ok((*binding, Flags::empty())), None => Err(Determinacy::Determined), }, - Scope::ExternPrelude => { - match this.reborrow().extern_prelude_get(ident, finalize.is_some()) { + Scope::ExternPreludeItems => { + // FIXME: use `finalize_scope` here. + match this.reborrow().extern_prelude_get_item(ident, finalize.is_some()) { Some(binding) => Ok((binding, Flags::empty())), None => Err(Determinacy::determined( this.graph_root.unexpanded_invocations.borrow().is_empty(), )), } } + Scope::ExternPreludeFlags => { + match this.extern_prelude_get_flag(ident, finalize_scope!().is_some()) { + Some(binding) => Ok((binding, Flags::empty())), + None => Err(Determinacy::Determined), + } + } Scope::ToolPrelude => match this.registered_tool_bindings.get(&ident) { Some(binding) => Ok((*binding, Flags::empty())), None => Err(Determinacy::Determined), @@ -599,8 +618,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if matches!(ident.name, sym::f16) && !this.tcx.features().f16() && !ident.span.allows_unstable(sym::f16) - && finalize.is_some() - && innermost_result.is_none() + && finalize_scope!().is_some() { feature_err( this.tcx.sess, @@ -613,8 +631,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if matches!(ident.name, sym::f128) && !this.tcx.features().f128() && !ident.span.allows_unstable(sym::f128) - && finalize.is_some() - && innermost_result.is_none() + && finalize_scope!().is_some() { feature_err( this.tcx.sess, @@ -632,17 +649,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match result { Ok((binding, flags)) => { - let binding_macro_kind = binding.macro_kind(); - // If we're looking for an attribute, that might be supported by a - // `macro_rules!` macro. - // FIXME: Replace this with tracking multiple macro kinds for one Def. - if !(sub_namespace_match(binding_macro_kind, macro_kind) - || (binding_macro_kind == Some(MacroKind::Bang) - && macro_kind == Some(MacroKind::Attr) - && this - .get_macro(binding.res()) - .is_some_and(|macro_data| macro_data.attr_ext.is_some()))) - { + if !sub_namespace_match(binding.macro_kinds(), macro_kind) { return None; } @@ -829,15 +836,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { assert_eq!(shadowing, Shadowing::Unrestricted); return if ns != TypeNS { Err((Determined, Weak::No)) - } else if let Some(binding) = - self.reborrow().extern_prelude_get(ident, finalize.is_some()) - { - Ok(binding) - } else if !self.graph_root.unexpanded_invocations.borrow().is_empty() { - // Macro-expanded `extern crate` items can add names to extern prelude. - Err((Undetermined, Weak::No)) } else { - Err((Determined, Weak::No)) + let binding = self.early_resolve_ident_in_lexical_scope( + ident, + ScopeSet::ExternPrelude, + parent_scope, + finalize, + finalize.is_some(), + ignore_binding, + ignore_import, + ); + return binding.map_err(|determinacy| (determinacy, Weak::No)); }; } ModuleOrUniformRoot::CurrentScope => { |
