diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
commit | e02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch) | |
tree | fd60ebbbb5299e16e5fca8c773ddb74f764760db /compiler/rustc_resolve/src/lib.rs | |
parent | Adding debian version 1.73.0+dfsg1-1. (diff) | |
download | rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.tar.xz rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_resolve/src/lib.rs')
-rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 137 |
1 files changed, 104 insertions, 33 deletions
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 76e54e60d..949c6ab5a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -18,7 +18,7 @@ #![recursion_limit = "256"] #![allow(rustdoc::private_intra_doc_links)] #![allow(rustc::potential_query_instability)] -#![cfg_attr(not(bootstrap), allow(internal_features))] +#![allow(internal_features)] #[macro_use] extern crate tracing; @@ -34,18 +34,20 @@ use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArg use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{Lrc, MappedReadGuard}; +use rustc_data_structures::sync::{FreezeReadGuard, Lrc}; use rustc_errors::{ Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage, }; use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; +use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_fluent_macro::fluent_messages; use rustc_hir::def::Namespace::{self, *}; +use rustc_hir::def::NonMacroAttrKind; use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; -use rustc_hir::TraitCandidate; +use rustc_hir::{PrimTy, TraitCandidate}; use rustc_index::IndexVec; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; @@ -184,8 +186,8 @@ struct BindingError { #[derive(Debug)] enum ResolutionError<'a> { - /// Error E0401: can't use type or const parameters from outer function. - GenericParamsFromOuterFunction(Res, HasGenericParams), + /// Error E0401: can't use type or const parameters from outer item. + GenericParamsFromOuterItem(Res, HasGenericParams), /// Error E0403: the name is already used for a type or const parameter in this generic /// parameter list. NameAlreadyUsedInParameterList(Symbol, Span), @@ -517,7 +519,7 @@ struct ModuleData<'a> { /// All modules are unique and allocated on a same arena, /// so we can use referential equality to compare them. -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] #[rustc_pass_by_value] struct Module<'a>(Interned<'a, ModuleData<'a>>); @@ -879,14 +881,33 @@ impl<'a> NameBindingData<'a> { invoc_parent_expansion.is_descendant_of(self_parent_expansion); !(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously) } + + // Its purpose is to postpone the determination of a single binding because + // we can't predict whether it will be overwritten by recently expanded macros. + // FIXME: How can we integrate it with the `update_resolution`? + fn determined(&self) -> bool { + match &self.kind { + NameBindingKind::Import { binding, import, .. } if import.is_glob() => { + import.parent_scope.module.unexpanded_invocations.borrow().is_empty() + && binding.determined() + } + _ => true, + } + } } #[derive(Default, Clone)] struct ExternPreludeEntry<'a> { - extern_crate_item: Option<NameBinding<'a>>, + binding: Option<NameBinding<'a>>, introduced_by_item: bool, } +impl ExternPreludeEntry<'_> { + fn is_import(&self) -> bool { + self.binding.is_some_and(|binding| binding.is_import()) + } +} + /// Used for better errors for E0773 enum BuiltinMacroState { NotYetSeen(SyntaxExtensionKind), @@ -981,7 +1002,6 @@ pub struct Resolver<'a, 'tcx> { glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>, /// Visibilities in "lowered" form, for all entities that have them. visibilities: FxHashMap<LocalDefId, ty::Visibility>, - has_pub_restricted: bool, used_imports: FxHashSet<NodeId>, maybe_unused_trait_imports: FxIndexSet<LocalDefId>, @@ -996,6 +1016,12 @@ pub struct Resolver<'a, 'tcx> { arenas: &'a ResolverArenas<'a>, dummy_binding: NameBinding<'a>, + builtin_types_bindings: FxHashMap<Symbol, NameBinding<'a>>, + builtin_attrs_bindings: FxHashMap<Symbol, NameBinding<'a>>, + registered_tool_bindings: FxHashMap<Ident, NameBinding<'a>>, + /// Binding for implicitly declared names that come with a module, + /// like `self` (not yet used), or `crate`/`$crate` (for root modules). + module_self_bindings: FxHashMap<Module<'a>, NameBinding<'a>>, used_extern_options: FxHashSet<Symbol>, macro_names: FxHashSet<Ident>, @@ -1033,7 +1059,7 @@ pub struct Resolver<'a, 'tcx> { /// `macro_rules` scopes produced by `macro_rules` item definitions. macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'a>>, /// Helper attributes that are in scope for the given expansion. - helper_attrs: FxHashMap<LocalExpnId, Vec<Ident>>, + helper_attrs: FxHashMap<LocalExpnId, Vec<(Ident, NameBinding<'a>)>>, /// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute /// with the given `ExpnId`. derive_data: FxHashMap<LocalExpnId, DeriveData>, @@ -1111,6 +1137,7 @@ impl<'a> ResolverArenas<'a> { span: Span, no_implicit_prelude: bool, module_map: &mut FxHashMap<DefId, Module<'a>>, + module_self_bindings: &mut FxHashMap<Module<'a>, NameBinding<'a>>, ) -> Module<'a> { let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new( parent, @@ -1125,6 +1152,9 @@ impl<'a> ResolverArenas<'a> { } if let Some(def_id) = def_id { module_map.insert(def_id, module); + let vis = ty::Visibility::<DefId>::Public; + let binding = (module, vis, module.span, LocalExpnId::ROOT).to_name_binding(self); + module_self_bindings.insert(module, binding); } module } @@ -1236,6 +1266,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ) -> Resolver<'a, 'tcx> { let root_def_id = CRATE_DEF_ID.to_def_id(); let mut module_map = FxHashMap::default(); + let mut module_self_bindings = FxHashMap::default(); let graph_root = arenas.new_module( None, ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty), @@ -1243,6 +1274,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { crate_span, attr::contains_name(attrs, sym::no_implicit_prelude), &mut module_map, + &mut module_self_bindings, ); let empty_module = arenas.new_module( None, @@ -1251,6 +1283,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { DUMMY_SP, true, &mut FxHashMap::default(), + &mut FxHashMap::default(), ); let mut visibilities = FxHashMap::default(); @@ -1283,6 +1316,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let registered_tools = tcx.registered_tools(()); let features = tcx.features(); + let pub_vis = ty::Visibility::<DefId>::Public; let mut resolver = Resolver { tcx, @@ -1320,7 +1354,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { glob_map: Default::default(), visibilities, - has_pub_restricted: false, used_imports: FxHashSet::default(), maybe_unused_trait_imports: Default::default(), @@ -1330,14 +1363,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { macro_expanded_macro_export_errors: BTreeSet::new(), arenas, - dummy_binding: arenas.alloc_name_binding(NameBindingData { - kind: NameBindingKind::Res(Res::Err), - ambiguity: None, - warn_ambiguity: false, - expansion: LocalExpnId::ROOT, - span: DUMMY_SP, - vis: ty::Visibility::Public, - }), + dummy_binding: (Res::Err, pub_vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(arenas), + builtin_types_bindings: PrimTy::ALL + .iter() + .map(|prim_ty| { + let binding = (Res::PrimTy(*prim_ty), pub_vis, DUMMY_SP, LocalExpnId::ROOT) + .to_name_binding(arenas); + (prim_ty.name(), binding) + }) + .collect(), + builtin_attrs_bindings: BUILTIN_ATTRIBUTES + .iter() + .map(|builtin_attr| { + let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(builtin_attr.name)); + let binding = + (res, pub_vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(arenas); + (builtin_attr.name, binding) + }) + .collect(), + registered_tool_bindings: registered_tools + .iter() + .map(|ident| { + let binding = (Res::ToolMod, pub_vis, ident.span, LocalExpnId::ROOT) + .to_name_binding(arenas); + (*ident, binding) + }) + .collect(), + module_self_bindings, used_extern_options: Default::default(), macro_names: FxHashSet::default(), @@ -1407,7 +1459,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { no_implicit_prelude: bool, ) -> Module<'a> { let module_map = &mut self.module_map; - self.arenas.new_module(parent, kind, expn_id, span, no_implicit_prelude, module_map) + let module_self_bindings = &mut self.module_self_bindings; + self.arenas.new_module( + parent, + kind, + expn_id, + span, + no_implicit_prelude, + module_map, + module_self_bindings, + ) } fn next_node_id(&mut self) -> NodeId { @@ -1436,7 +1497,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let expn_that_defined = self.expn_that_defined; let visibilities = self.visibilities; - let has_pub_restricted = self.has_pub_restricted; let extern_crate_map = self.extern_crate_map; let maybe_unused_trait_imports = self.maybe_unused_trait_imports; let glob_map = self.glob_map; @@ -1454,7 +1514,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let global_ctxt = ResolverGlobalCtxt { expn_that_defined, visibilities, - has_pub_restricted, effective_visibilities, extern_crate_map, module_children: self.module_children, @@ -1498,7 +1557,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { )) } - fn cstore(&self) -> MappedReadGuard<'_, CStore> { + fn cstore(&self) -> FreezeReadGuard<'_, CStore> { CStore::from_tcx(self.tcx) } @@ -1553,7 +1612,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }); // Make sure we don't mutate the cstore from here on. - self.tcx.untracked().cstore.leak(); + self.tcx.untracked().cstore.freeze(); } fn traits_in_scope( @@ -1727,7 +1786,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // but not introduce it, as used if they are accessed from lexical scope. if is_lexical_scope { if let Some(entry) = self.extern_prelude.get(&ident.normalize_to_macros_2_0()) { - if !entry.introduced_by_item && entry.extern_crate_item == Some(used_binding) { + if !entry.introduced_by_item && entry.binding == Some(used_binding) { return; } } @@ -1885,12 +1944,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Make sure `self`, `super` etc produce an error when passed to here. return None; } - self.extern_prelude.get(&ident.normalize_to_macros_2_0()).cloned().and_then(|entry| { - if let Some(binding) = entry.extern_crate_item { - if finalize && entry.introduced_by_item { - self.record_use(ident, binding, false); + + 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 { + if finalize { + if !entry.is_import() { + self.crate_loader(|c| c.process_path_extern(ident.name, ident.span)); + } else if entry.introduced_by_item { + self.record_use(ident, binding, false); + } } - Some(binding) + binding } else { let crate_id = if finalize { let Some(crate_id) = @@ -1903,10 +1968,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.crate_loader(|c| c.maybe_process_path_extern(ident.name))? }; let crate_root = self.expect_module(crate_id.as_def_id()); - let vis = ty::Visibility::<LocalDefId>::Public; - Some((crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas)) - } - }) + let vis = ty::Visibility::<DefId>::Public; + (crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas) + }) + }); + + if let Some(entry) = self.extern_prelude.get_mut(&norm_ident) { + entry.binding = binding; + } + + binding } /// Rustdoc uses this to resolve doc link paths in a recoverable way. `PathResult<'a>` |