summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_resolve/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_resolve/src/lib.rs')
-rw-r--r--compiler/rustc_resolve/src/lib.rs137
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>`