diff options
Diffstat (limited to 'compiler/rustc_resolve/src/lib.rs')
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 91 |
1 files changed, 61 insertions, 30 deletions
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 948b67a3798..dbde6f7cfd7 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -21,7 +21,7 @@ #![recursion_limit = "256"] // tidy-alphabetical-end -use std::cell::{Cell, RefCell}; +use std::cell::{Cell, Ref, RefCell}; use std::collections::BTreeSet; use std::fmt; use std::sync::Arc; @@ -41,7 +41,6 @@ use rustc_ast::{ self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, Expr, ExprKind, GenericArg, GenericArgs, LitKind, NodeId, Path, attr, }; -use rustc_attr_data_structures::StrippedCfgItem; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::steal::Steal; @@ -50,6 +49,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; use rustc_feature::BUILTIN_ATTRIBUTES; +use rustc_hir::attrs::StrippedCfgItem; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{ self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS, @@ -64,8 +64,8 @@ use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{ - self, DelegationFnSig, Feed, MainDefinition, RegisteredTools, ResolverGlobalCtxt, - ResolverOutputs, TyCtxt, TyCtxtFeed, Visibility, + self, DelegationFnSig, Feed, MainDefinition, RegisteredTools, ResolverAstLowering, + ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, }; use rustc_query_system::ich::StableHashingContext; use rustc_session::lint::builtin::PRIVATE_MACRO_USE; @@ -119,7 +119,6 @@ enum Scope<'ra> { DeriveHelpers(LocalExpnId), DeriveHelpersCompat, MacroRules(MacroRulesScopeRef<'ra>), - CrateRoot, // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` // lint if it should be reported. Module(Module<'ra>, Option<NodeId>), @@ -139,8 +138,8 @@ enum Scope<'ra> { enum ScopeSet<'ra> { /// All scopes with the given namespace. All(Namespace), - /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros). - AbsolutePath(Namespace), + /// A module, then extern prelude (used for mixed 2015-2018 mode in macros). + ModuleAndExternPrelude(Namespace, Module<'ra>), /// All scopes with macro namespace and the given macro kind restriction. Macro(MacroKind), /// All scopes with the given namespace, used for partially performing late resolution. @@ -419,8 +418,10 @@ enum ModuleOrUniformRoot<'ra> { /// Regular module. Module(Module<'ra>), - /// Virtual module that denotes resolution in crate root with fallback to extern prelude. - CrateRootAndExternPrelude, + /// Virtual module that denotes resolution in a module with fallback to extern prelude. + /// Used for paths starting with `::` coming from 2015 edition macros + /// used in 2018+ edition crates. + ModuleAndExternPrelude(Module<'ra>), /// Virtual module that denotes resolution in extern prelude. /// Used for paths starting with `::` on 2018 edition. @@ -579,6 +580,8 @@ struct ModuleData<'ra> { lazy_resolutions: Resolutions<'ra>, /// True if this is a module from other crate that needs to be populated on access. populate_on_access: Cell<bool>, + /// Used to disambiguate underscore items (`const _: T = ...`) in the module. + underscore_disambiguator: Cell<u32>, /// Macro invocations that can expand into items in this module. unexpanded_invocations: RefCell<FxHashSet<LocalExpnId>>, @@ -639,6 +642,7 @@ impl<'ra> ModuleData<'ra> { kind, lazy_resolutions: Default::default(), populate_on_access: Cell::new(is_foreign), + underscore_disambiguator: Cell::new(0), unexpanded_invocations: Default::default(), no_implicit_prelude, glob_importers: RefCell::new(Vec::new()), @@ -652,11 +656,23 @@ impl<'ra> ModuleData<'ra> { } impl<'ra> Module<'ra> { - fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F) - where - R: AsMut<Resolver<'ra, 'tcx>>, - F: FnMut(&mut R, Ident, Namespace, NameBinding<'ra>), - { + fn for_each_child<'tcx, R: AsRef<Resolver<'ra, 'tcx>>>( + self, + resolver: &R, + mut f: impl FnMut(&R, Ident, Namespace, NameBinding<'ra>), + ) { + for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() { + if let Some(binding) = name_resolution.borrow().best_binding() { + f(resolver, key.ident, key.ns, binding); + } + } + } + + fn for_each_child_mut<'tcx, R: AsMut<Resolver<'ra, 'tcx>>>( + self, + resolver: &mut R, + mut f: impl FnMut(&mut R, Ident, Namespace, NameBinding<'ra>), + ) { for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() { if let Some(binding) = name_resolution.borrow().best_binding() { f(resolver, key.ident, key.ns, binding); @@ -665,10 +681,7 @@ impl<'ra> Module<'ra> { } /// This modifies `self` in place. The traits will be stored in `self.traits`. - fn ensure_traits<'tcx, R>(self, resolver: &mut R) - where - R: AsMut<Resolver<'ra, 'tcx>>, - { + fn ensure_traits<'tcx>(self, resolver: &impl AsRef<Resolver<'ra, 'tcx>>) { let mut traits = self.traits.borrow_mut(); if traits.is_none() { let mut collected_traits = Vec::new(); @@ -677,7 +690,7 @@ impl<'ra> Module<'ra> { return; } if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() { - collected_traits.push((name, binding, r.as_mut().get_module(def_id))) + collected_traits.push((name, binding, r.as_ref().get_module(def_id))) } }); *traits = Some(collected_traits.into_boxed_slice()); @@ -996,13 +1009,13 @@ impl<'ra> NameBindingData<'ra> { #[derive(Default, Clone)] struct ExternPreludeEntry<'ra> { - binding: Option<NameBinding<'ra>>, + binding: Cell<Option<NameBinding<'ra>>>, introduced_by_item: bool, } impl ExternPreludeEntry<'_> { fn is_import(&self) -> bool { - self.binding.is_some_and(|binding| binding.is_import()) + self.binding.get().is_some_and(|binding| binding.is_import()) } } @@ -1024,6 +1037,11 @@ impl MacroData { } } +pub struct ResolverOutputs { + pub global_ctxt: ResolverGlobalCtxt, + pub ast_lowering: ResolverAstLowering, +} + /// The main resolver class. /// /// This is the visitor that walks the whole crate. @@ -1336,6 +1354,12 @@ impl<'ra, 'tcx> AsMut<Resolver<'ra, 'tcx>> for Resolver<'ra, 'tcx> { } } +impl<'ra, 'tcx> AsRef<Resolver<'ra, 'tcx>> for Resolver<'ra, 'tcx> { + fn as_ref(&self) -> &Resolver<'ra, 'tcx> { + self + } +} + impl<'tcx> Resolver<'_, 'tcx> { fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> { self.opt_feed(node).map(|f| f.key()) @@ -1857,7 +1881,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // We don't reject trait aliases (`trait_module == None`) because we don't have access to their // associated items. fn trait_may_have_item( - &mut self, + &self, trait_module: Option<Module<'ra>>, assoc_item: Option<(Symbol, Namespace)>, ) -> bool { @@ -1889,7 +1913,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { import_ids } - fn resolutions(&mut self, module: Module<'ra>) -> &'ra Resolutions<'ra> { + fn resolutions(&self, module: Module<'ra>) -> &'ra Resolutions<'ra> { if module.populate_on_access.get() { module.populate_on_access.set(false); self.build_reduced_graph_external(module); @@ -1898,12 +1922,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn resolution( - &mut self, + &self, + module: Module<'ra>, + key: BindingKey, + ) -> Option<Ref<'ra, NameResolution<'ra>>> { + self.resolutions(module).borrow().get(&key).map(|resolution| resolution.borrow()) + } + + fn resolution_or_default( + &self, module: Module<'ra>, key: BindingKey, ) -> &'ra RefCell<NameResolution<'ra>> { - *self - .resolutions(module) + self.resolutions(module) .borrow_mut() .entry(key) .or_insert_with(|| self.arenas.alloc_name_resolution()) @@ -1980,7 +2011,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // but not introduce it, as used if they are accessed from lexical scope. if used == Used::Scope { if let Some(entry) = self.extern_prelude.get(&ident.normalize_to_macros_2_0()) { - if !entry.introduced_by_item && entry.binding == Some(used_binding) { + if !entry.introduced_by_item && entry.binding.get() == Some(used_binding) { return; } } @@ -2144,7 +2175,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let norm_ident = ident.normalize_to_macros_2_0(); let binding = self.extern_prelude.get(&norm_ident).cloned().and_then(|entry| { - Some(if let Some(binding) = entry.binding { + Some(if let Some(binding) = entry.binding.get() { if finalize { if !entry.is_import() { self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span); @@ -2169,8 +2200,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) }); - if let Some(entry) = self.extern_prelude.get_mut(&norm_ident) { - entry.binding = binding; + if let Some(entry) = self.extern_prelude.get(&norm_ident) { + entry.binding.set(binding); } binding |
