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.rs72
1 files changed, 49 insertions, 23 deletions
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 8aebb7da1..a0fa61c45 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -73,6 +73,7 @@ mod check_unused;
mod def_collector;
mod diagnostics;
mod effective_visibilities;
+mod errors;
mod ident;
mod imports;
mod late;
@@ -646,7 +647,7 @@ impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> {
#[derive(Clone, Debug)]
enum NameBindingKind<'a> {
- Res(Res, /* is_macro_export */ bool),
+ Res(Res),
Module(Module<'a>),
Import { binding: &'a NameBinding<'a>, import: &'a Import<'a>, used: Cell<bool> },
}
@@ -745,7 +746,7 @@ impl<'a> NameBinding<'a> {
fn res(&self) -> Res {
match self.kind {
- NameBindingKind::Res(res, _) => res,
+ NameBindingKind::Res(res) => res,
NameBindingKind::Module(module) => module.res().unwrap(),
NameBindingKind::Import { binding, .. } => binding.res(),
}
@@ -762,10 +763,10 @@ impl<'a> NameBinding<'a> {
fn is_possibly_imported_variant(&self) -> bool {
match self.kind {
NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(),
- NameBindingKind::Res(
- Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _),
+ NameBindingKind::Res(Res::Def(
+ DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..),
_,
- ) => true,
+ )) => true,
NameBindingKind::Res(..) | NameBindingKind::Module(..) => false,
}
}
@@ -788,6 +789,13 @@ impl<'a> NameBinding<'a> {
matches!(self.kind, NameBindingKind::Import { .. })
}
+ /// The binding introduced by `#[macro_export] macro_rules` is a public import, but it might
+ /// not be perceived as such by users, so treat it as a non-import in some diagnostics.
+ fn is_import_user_facing(&self) -> bool {
+ matches!(self.kind, NameBindingKind::Import { import, .. }
+ if !matches!(import.kind, ImportKind::MacroExport))
+ }
+
fn is_glob_import(&self) -> bool {
match self.kind {
NameBindingKind::Import { import, .. } => import.is_glob(),
@@ -1030,6 +1038,8 @@ pub struct Resolver<'a> {
/// they are declared in the static array generated by proc_macro_harness.
proc_macros: Vec<NodeId>,
confused_type_with_std_module: FxHashMap<Span, Span>,
+ /// Whether lifetime elision was successful.
+ lifetime_elision_allowed: FxHashSet<NodeId>,
effective_visibilities: EffectiveVisibilities,
}
@@ -1101,17 +1111,30 @@ impl<'a> AsMut<Resolver<'a>> for Resolver<'a> {
}
}
-impl<'a, 'b> DefIdTree for &'a Resolver<'b> {
+/// A minimal subset of resolver that can implemenent `DefIdTree`, sometimes
+/// required to satisfy borrow checker by avoiding borrowing the whole resolver.
+#[derive(Clone, Copy)]
+struct ResolverTree<'a, 'b>(&'a Definitions, &'a CrateLoader<'b>);
+
+impl DefIdTree for ResolverTree<'_, '_> {
#[inline]
fn opt_parent(self, id: DefId) -> Option<DefId> {
+ let ResolverTree(definitions, crate_loader) = self;
match id.as_local() {
- Some(id) => self.definitions.def_key(id).parent,
- None => self.cstore().def_key(id).parent,
+ Some(id) => definitions.def_key(id).parent,
+ None => crate_loader.cstore().def_key(id).parent,
}
.map(|index| DefId { index, ..id })
}
}
+impl<'a, 'b> DefIdTree for &'a Resolver<'b> {
+ #[inline]
+ fn opt_parent(self, id: DefId) -> Option<DefId> {
+ ResolverTree(&self.definitions, &self.crate_loader).opt_parent(id)
+ }
+}
+
impl Resolver<'_> {
fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
self.node_id_to_def_id.get(&node).copied()
@@ -1175,7 +1198,7 @@ impl<'a> Resolver<'a> {
pub fn new(
session: &'a Session,
krate: &Crate,
- crate_name: &str,
+ crate_name: Symbol,
metadata_loader: Box<MetadataLoaderDyn>,
arenas: &'a ResolverArenas<'a>,
) -> Resolver<'a> {
@@ -1283,7 +1306,7 @@ impl<'a> Resolver<'a> {
arenas,
dummy_binding: arenas.alloc_name_binding(NameBinding {
- kind: NameBindingKind::Res(Res::Err, false),
+ kind: NameBindingKind::Res(Res::Err),
ambiguity: None,
expansion: LocalExpnId::ROOT,
span: DUMMY_SP,
@@ -1335,6 +1358,7 @@ impl<'a> Resolver<'a> {
trait_impls: Default::default(),
proc_macros: Default::default(),
confused_type_with_std_module: Default::default(),
+ lifetime_elision_allowed: Default::default(),
effective_visibilities: Default::default(),
};
@@ -1429,6 +1453,7 @@ impl<'a> Resolver<'a> {
def_id_to_node_id: self.def_id_to_node_id,
trait_map: self.trait_map,
builtin_macro_kinds: self.builtin_macro_kinds,
+ lifetime_elision_allowed: self.lifetime_elision_allowed,
};
ResolverOutputs { definitions, global_ctxt, ast_lowering }
}
@@ -1472,6 +1497,7 @@ impl<'a> Resolver<'a> {
def_id_to_node_id: self.def_id_to_node_id.clone(),
trait_map: self.trait_map.clone(),
builtin_macro_kinds: self.builtin_macro_kinds.clone(),
+ lifetime_elision_allowed: self.lifetime_elision_allowed.clone(),
};
ResolverOutputs { definitions, global_ctxt, ast_lowering }
}
@@ -1613,10 +1639,12 @@ impl<'a> Resolver<'a> {
) -> SmallVec<[LocalDefId; 1]> {
let mut import_ids = smallvec![];
while let NameBindingKind::Import { import, binding, .. } = kind {
- let id = self.local_def_id(import.id);
- self.maybe_unused_trait_imports.insert(id);
+ if let Some(node_id) = import.id() {
+ let def_id = self.local_def_id(node_id);
+ self.maybe_unused_trait_imports.insert(def_id);
+ import_ids.push(def_id);
+ }
self.add_to_glob_map(&import, trait_name);
- import_ids.push(id);
kind = &binding.kind;
}
import_ids
@@ -1683,7 +1711,9 @@ impl<'a> Resolver<'a> {
}
used.set(true);
import.used.set(true);
- self.used_imports.insert(import.id);
+ if let Some(id) = import.id() {
+ self.used_imports.insert(id);
+ }
self.add_to_glob_map(&import, ident);
self.record_use(ident, binding, false);
}
@@ -1691,8 +1721,8 @@ impl<'a> Resolver<'a> {
#[inline]
fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) {
- if import.is_glob() {
- let def_id = self.local_def_id(import.id);
+ if let ImportKind::Glob { id, .. } = import.kind {
+ let def_id = self.local_def_id(id);
self.glob_map.entry(def_id).or_default().insert(ident.name);
}
}
@@ -1897,7 +1927,7 @@ impl<'a> Resolver<'a> {
if let Some(def_id) = def_id.as_local() {
self.reexport_map.get(&def_id).cloned().unwrap_or_default()
} else {
- self.cstore().module_children_untracked(def_id, self.session)
+ self.cstore().module_children_untracked(def_id, self.session).collect()
}
}
@@ -1961,7 +1991,7 @@ impl<'a> Resolver<'a> {
.find(|a| a.has_name(sym::rustc_legacy_const_generics))?;
let mut ret = Vec::new();
for meta in attr.meta_item_list()? {
- match meta.literal()?.kind {
+ match meta.lit()?.kind {
LitKind::Int(a, _) => ret.push(a as usize),
_ => panic!("invalid arg index"),
}
@@ -1999,11 +2029,7 @@ impl<'a> Resolver<'a> {
// Items that go to reexport table encoded to metadata and visible through it to other crates.
fn is_reexport(&self, binding: &NameBinding<'a>) -> Option<def::Res<!>> {
- // FIXME: Consider changing the binding inserted by `#[macro_export] macro_rules`
- // into the crate root to actual `NameBindingKind::Import`.
- if binding.is_import()
- || matches!(binding.kind, NameBindingKind::Res(_, _is_macro_export @ true))
- {
+ if binding.is_import() {
let res = binding.res().expect_non_local();
// Ambiguous imports are treated as errors at this point and are
// not exposed to other crates (see #36837 for more details).