mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Rollup merge of #113332 - petrochenkov:bindintern, r=cjgillot
resolve: Use `Interned` for some interned structures Enough to get rid of all existing `ptr::eq`s and "partial" uses of `Interned`.
This commit is contained in:
commit
01627265e3
@ -6,10 +6,10 @@
|
||||
//! Imports are also considered items and placed into modules here, but not resolved yet.
|
||||
|
||||
use crate::def_collector::collect_definitions;
|
||||
use crate::imports::{Import, ImportKind};
|
||||
use crate::imports::{ImportData, ImportKind};
|
||||
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
|
||||
use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
|
||||
use crate::{errors, BindingKey, MacroData};
|
||||
use crate::{errors, BindingKey, MacroData, NameBindingData};
|
||||
use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot};
|
||||
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError};
|
||||
use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError};
|
||||
@ -31,15 +31,14 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::ptr;
|
||||
|
||||
type Res = def::Res<NodeId>;
|
||||
|
||||
impl<'a, Id: Into<DefId>> ToNameBinding<'a>
|
||||
for (Module<'a>, ty::Visibility<Id>, Span, LocalExpnId)
|
||||
{
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
|
||||
arenas.alloc_name_binding(NameBinding {
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a> {
|
||||
arenas.alloc_name_binding(NameBindingData {
|
||||
kind: NameBindingKind::Module(self.0),
|
||||
ambiguity: None,
|
||||
vis: self.1.to_def_id(),
|
||||
@ -50,8 +49,8 @@ impl<'a, Id: Into<DefId>> ToNameBinding<'a>
|
||||
}
|
||||
|
||||
impl<'a, Id: Into<DefId>> ToNameBinding<'a> for (Res, ty::Visibility<Id>, Span, LocalExpnId) {
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
|
||||
arenas.alloc_name_binding(NameBinding {
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a> {
|
||||
arenas.alloc_name_binding(NameBindingData {
|
||||
kind: NameBindingKind::Res(self.0),
|
||||
ambiguity: None,
|
||||
vis: self.1.to_def_id(),
|
||||
@ -71,7 +70,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
let binding = def.to_name_binding(self.arenas);
|
||||
let key = self.new_disambiguated_key(ident, ns);
|
||||
if let Err(old_binding) = self.try_define(parent, key, binding) {
|
||||
self.report_conflict(parent, ident, ns, old_binding, &binding);
|
||||
self.report_conflict(parent, ident, ns, old_binding, binding);
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,8 +141,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
Some(def_id) => self.macro_def_scope(def_id),
|
||||
None => expn_id
|
||||
.as_local()
|
||||
.and_then(|expn_id| self.ast_transform_scopes.get(&expn_id))
|
||||
.unwrap_or(&self.graph_root),
|
||||
.and_then(|expn_id| self.ast_transform_scopes.get(&expn_id).copied())
|
||||
.unwrap_or(self.graph_root),
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,7 +353,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
vis: ty::Visibility,
|
||||
) {
|
||||
let current_module = self.parent_scope.module;
|
||||
let import = self.r.arenas.alloc_import(Import {
|
||||
let import = self.r.arenas.alloc_import(ImportData {
|
||||
kind,
|
||||
parent_scope: self.parent_scope,
|
||||
module_path,
|
||||
@ -378,7 +377,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
if !type_ns_only || ns == TypeNS {
|
||||
let key = BindingKey::new(target, ns);
|
||||
let mut resolution = this.resolution(current_module, key).borrow_mut();
|
||||
resolution.add_single_import(import);
|
||||
resolution.single_imports.insert(import);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -848,7 +847,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
(used, Some(ModuleOrUniformRoot::Module(module)), binding)
|
||||
})
|
||||
.unwrap_or((true, None, self.r.dummy_binding));
|
||||
let import = self.r.arenas.alloc_import(Import {
|
||||
let import = self.r.arenas.alloc_import(ImportData {
|
||||
kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
|
||||
root_id: item.id,
|
||||
parent_scope: self.parent_scope,
|
||||
@ -864,7 +863,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
});
|
||||
self.r.potentially_unused_imports.push(import);
|
||||
let imported_binding = self.r.import(binding, import);
|
||||
if ptr::eq(parent, self.r.graph_root) {
|
||||
if parent == self.r.graph_root {
|
||||
if let Some(entry) = self.r.extern_prelude.get(&ident.normalize_to_macros_2_0()) {
|
||||
if expansion != LocalExpnId::ROOT
|
||||
&& orig_name.is_some()
|
||||
@ -996,7 +995,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
fn add_macro_use_binding(
|
||||
&mut self,
|
||||
name: Symbol,
|
||||
binding: &'a NameBinding<'a>,
|
||||
binding: NameBinding<'a>,
|
||||
span: Span,
|
||||
allow_shadowing: bool,
|
||||
) {
|
||||
@ -1058,7 +1057,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
}
|
||||
|
||||
let macro_use_import = |this: &Self, span| {
|
||||
this.r.arenas.alloc_import(Import {
|
||||
this.r.arenas.alloc_import(ImportData {
|
||||
kind: ImportKind::MacroUse,
|
||||
root_id: item.id,
|
||||
parent_scope: this.parent_scope,
|
||||
@ -1228,7 +1227,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
self.r.set_binding_parent_module(binding, parent_scope.module);
|
||||
self.r.all_macro_rules.insert(ident.name, res);
|
||||
if is_macro_export {
|
||||
let import = self.r.arenas.alloc_import(Import {
|
||||
let import = self.r.arenas.alloc_import(ImportData {
|
||||
kind: ImportKind::MacroExport,
|
||||
root_id: item.id,
|
||||
parent_scope: self.parent_scope,
|
||||
|
@ -1,5 +1,3 @@
|
||||
use std::ptr;
|
||||
|
||||
use rustc_ast::expand::StrippedCfgItem;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::{self, Visitor};
|
||||
@ -182,13 +180,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn report_conflict<'b>(
|
||||
pub(crate) fn report_conflict(
|
||||
&mut self,
|
||||
parent: Module<'_>,
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
new_binding: &NameBinding<'b>,
|
||||
old_binding: &NameBinding<'b>,
|
||||
new_binding: NameBinding<'a>,
|
||||
old_binding: NameBinding<'a>,
|
||||
) {
|
||||
// Error on the second of two conflicting names
|
||||
if old_binding.span.lo() > new_binding.span.lo() {
|
||||
@ -262,7 +260,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
// See https://github.com/rust-lang/rust/issues/32354
|
||||
use NameBindingKind::Import;
|
||||
let can_suggest = |binding: &NameBinding<'_>, import: &self::Import<'_>| {
|
||||
let can_suggest = |binding: NameBinding<'_>, import: self::Import<'_>| {
|
||||
!binding.span.is_dummy()
|
||||
&& !matches!(import.kind, ImportKind::MacroUse | ImportKind::MacroExport)
|
||||
};
|
||||
@ -272,22 +270,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
(Import { import: new, .. }, Import { import: old, .. })
|
||||
if {
|
||||
(new.has_attributes || old.has_attributes)
|
||||
&& can_suggest(old_binding, old)
|
||||
&& can_suggest(new_binding, new)
|
||||
&& can_suggest(old_binding, *old)
|
||||
&& can_suggest(new_binding, *new)
|
||||
} =>
|
||||
{
|
||||
if old.has_attributes {
|
||||
Some((new, new_binding.span, true))
|
||||
Some((*new, new_binding.span, true))
|
||||
} else {
|
||||
Some((old, old_binding.span, true))
|
||||
Some((*old, old_binding.span, true))
|
||||
}
|
||||
}
|
||||
// Otherwise prioritize the new binding.
|
||||
(Import { import, .. }, other) if can_suggest(new_binding, import) => {
|
||||
Some((import, new_binding.span, other.is_import()))
|
||||
(Import { import, .. }, other) if can_suggest(new_binding, *import) => {
|
||||
Some((*import, new_binding.span, other.is_import()))
|
||||
}
|
||||
(other, Import { import, .. }) if can_suggest(old_binding, import) => {
|
||||
Some((import, old_binding.span, other.is_import()))
|
||||
(other, Import { import, .. }) if can_suggest(old_binding, *import) => {
|
||||
Some((*import, old_binding.span, other.is_import()))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
@ -341,7 +339,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
name: Symbol,
|
||||
import: &Import<'_>,
|
||||
import: Import<'_>,
|
||||
binding_span: Span,
|
||||
) {
|
||||
let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
|
||||
@ -413,7 +411,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
fn add_suggestion_for_duplicate_nested_use(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
import: &Import<'_>,
|
||||
import: Import<'_>,
|
||||
binding_span: Span,
|
||||
) {
|
||||
assert!(import.is_nested());
|
||||
@ -455,7 +453,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
&mut self,
|
||||
finalize: Option<Finalize>,
|
||||
path: &[Segment],
|
||||
second_binding: Option<&NameBinding<'_>>,
|
||||
second_binding: Option<NameBinding<'_>>,
|
||||
) {
|
||||
let Some(Finalize { node_id, root_span, .. }) = finalize else {
|
||||
return;
|
||||
@ -1198,7 +1196,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
// avoid suggesting anything with a hygienic name
|
||||
if ident.name == lookup_ident.name
|
||||
&& ns == namespace
|
||||
&& !ptr::eq(in_module, parent_scope.module)
|
||||
&& in_module != parent_scope.module
|
||||
&& !ident.span.normalize_to_macros_2_0().from_expansion()
|
||||
{
|
||||
let res = name_binding.res();
|
||||
@ -1515,7 +1513,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
true
|
||||
}
|
||||
|
||||
fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String {
|
||||
fn binding_description(&self, b: NameBinding<'_>, ident: Ident, from_prelude: bool) -> String {
|
||||
let res = b.res();
|
||||
if b.span.is_dummy() || !self.tcx.sess.source_map().is_span_accessible(b.span) {
|
||||
// These already contain the "built-in" prefix or look bad with it.
|
||||
@ -1555,7 +1553,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
err.span_label(ident.span, "ambiguous name");
|
||||
err.note(format!("ambiguous because of {}", kind.descr()));
|
||||
|
||||
let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| {
|
||||
let mut could_refer_to = |b: NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| {
|
||||
let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude);
|
||||
let note_msg = format!("`{ident}` could{also} refer to {what}");
|
||||
|
||||
@ -1595,7 +1593,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
/// If the binding refers to a tuple struct constructor with fields,
|
||||
/// returns the span of its fields.
|
||||
fn ctor_fields_span(&self, binding: &NameBinding<'_>) -> Option<Span> {
|
||||
fn ctor_fields_span(&self, binding: NameBinding<'_>) -> Option<Span> {
|
||||
if let NameBindingKind::Res(Res::Def(
|
||||
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn),
|
||||
ctor_def_id,
|
||||
@ -1622,7 +1620,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
if ctor_fields_span.is_some() { plain_descr + " constructor" } else { plain_descr };
|
||||
let import_descr = nonimport_descr.clone() + " import";
|
||||
let get_descr =
|
||||
|b: &NameBinding<'_>| if b.is_import() { &import_descr } else { &nonimport_descr };
|
||||
|b: NameBinding<'_>| if b.is_import() { &import_descr } else { &nonimport_descr };
|
||||
|
||||
// Print the primary message.
|
||||
let descr = get_descr(binding);
|
||||
@ -1702,7 +1700,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let first = ptr::eq(binding, first_binding);
|
||||
let first = binding == first_binding;
|
||||
let msg = format!(
|
||||
"{and_refers_to}the {item} `{name}`{which} is defined here{dots}",
|
||||
and_refers_to = if first { "" } else { "...and refers to " },
|
||||
@ -1732,7 +1730,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
pub(crate) fn find_similarly_named_module_or_crate(
|
||||
&mut self,
|
||||
ident: Symbol,
|
||||
current_module: &Module<'a>,
|
||||
current_module: Module<'a>,
|
||||
) -> Option<Symbol> {
|
||||
let mut candidates = self
|
||||
.extern_prelude
|
||||
@ -1742,7 +1740,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
self.module_map
|
||||
.iter()
|
||||
.filter(|(_, module)| {
|
||||
current_module.is_ancestor_of(module) && !ptr::eq(current_module, *module)
|
||||
current_module.is_ancestor_of(**module) && current_module != **module
|
||||
})
|
||||
.flat_map(|(_, module)| module.kind.name()),
|
||||
)
|
||||
@ -1762,7 +1760,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
opt_ns: Option<Namespace>, // `None` indicates a module path in import
|
||||
parent_scope: &ParentScope<'a>,
|
||||
ribs: Option<&PerNS<Vec<Rib<'a>>>>,
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
module: Option<ModuleOrUniformRoot<'a>>,
|
||||
failed_segment_idx: usize,
|
||||
ident: Ident,
|
||||
@ -1945,7 +1943,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
suggestion = suggestion.or_else(|| {
|
||||
self.find_similarly_named_module_or_crate(ident.name, &parent_scope.module).map(
|
||||
self.find_similarly_named_module_or_crate(ident.name, parent_scope.module).map(
|
||||
|sugg| {
|
||||
(
|
||||
vec![(ident.span, sugg.to_string())],
|
||||
@ -2114,7 +2112,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
/// ```
|
||||
pub(crate) fn check_for_module_export_macro(
|
||||
&mut self,
|
||||
import: &'a Import<'a>,
|
||||
import: Import<'a>,
|
||||
module: ModuleOrUniformRoot<'a>,
|
||||
ident: Ident,
|
||||
) -> Option<(Option<Suggestion>, Option<String>)> {
|
||||
@ -2126,9 +2124,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
crate_module = parent;
|
||||
}
|
||||
|
||||
if ModuleOrUniformRoot::same_def(ModuleOrUniformRoot::Module(crate_module), module) {
|
||||
// Don't make a suggestion if the import was already from the root of the
|
||||
// crate.
|
||||
if module == ModuleOrUniformRoot::Module(crate_module) {
|
||||
// Don't make a suggestion if the import was already from the root of the crate.
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ use rustc_ast::visit::Visitor;
|
||||
use rustc_ast::Crate;
|
||||
use rustc_ast::EnumDef;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
||||
use rustc_middle::middle::privacy::Level;
|
||||
@ -13,12 +12,10 @@ use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility};
|
||||
use rustc_middle::ty::Visibility;
|
||||
use std::mem;
|
||||
|
||||
type ImportId<'a> = Interned<'a, NameBinding<'a>>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum ParentId<'a> {
|
||||
Def(LocalDefId),
|
||||
Import(ImportId<'a>),
|
||||
Import(NameBinding<'a>),
|
||||
}
|
||||
|
||||
impl ParentId<'_> {
|
||||
@ -36,7 +33,7 @@ pub(crate) struct EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
|
||||
/// While walking import chains we need to track effective visibilities per-binding, and def id
|
||||
/// keys in `Resolver::effective_visibilities` are not enough for that, because multiple
|
||||
/// bindings can correspond to a single def id in imports. So we keep a separate table.
|
||||
import_effective_visibilities: EffectiveVisibilities<ImportId<'a>>,
|
||||
import_effective_visibilities: EffectiveVisibilities<NameBinding<'a>>,
|
||||
// It's possible to recalculate this at any point, but it's relatively expensive.
|
||||
current_private_vis: Visibility,
|
||||
changed: bool,
|
||||
@ -47,7 +44,7 @@ impl Resolver<'_, '_> {
|
||||
self.get_nearest_non_block_module(def_id.to_def_id()).nearest_parent_mod().expect_local()
|
||||
}
|
||||
|
||||
fn private_vis_import(&mut self, binding: ImportId<'_>) -> Visibility {
|
||||
fn private_vis_import(&mut self, binding: NameBinding<'_>) -> Visibility {
|
||||
let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() };
|
||||
Visibility::Restricted(
|
||||
import
|
||||
@ -75,7 +72,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
|
||||
pub(crate) fn compute_effective_visibilities<'c>(
|
||||
r: &'r mut Resolver<'a, 'tcx>,
|
||||
krate: &'c Crate,
|
||||
) -> FxHashSet<Interned<'a, NameBinding<'a>>> {
|
||||
) -> FxHashSet<NameBinding<'a>> {
|
||||
let mut visitor = EffectiveVisibilitiesVisitor {
|
||||
r,
|
||||
def_effective_visibilities: Default::default(),
|
||||
@ -133,8 +130,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
|
||||
// lint. For all bindings added to the table this way `is_ambiguity` returns true.
|
||||
let mut parent_id = ParentId::Def(module_id);
|
||||
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
|
||||
let binding_id = ImportId::new_unchecked(binding);
|
||||
self.update_import(binding_id, parent_id);
|
||||
self.update_import(binding, parent_id);
|
||||
|
||||
if binding.ambiguity.is_some() {
|
||||
// Stop at the root ambiguity, further bindings in the chain should not
|
||||
@ -143,7 +139,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
|
||||
break;
|
||||
}
|
||||
|
||||
parent_id = ParentId::Import(binding_id);
|
||||
parent_id = ParentId::Import(binding);
|
||||
binding = nested_binding;
|
||||
}
|
||||
|
||||
@ -192,7 +188,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_import(&mut self, binding: ImportId<'a>, parent_id: ParentId<'a>) {
|
||||
fn update_import(&mut self, binding: NameBinding<'a>, parent_id: ParentId<'a>) {
|
||||
let nominal_vis = binding.vis.expect_local();
|
||||
let Some(cheap_private_vis) = self.may_update(nominal_vis, parent_id) else { return };
|
||||
let inherited_eff_vis = self.effective_vis_or_private(parent_id);
|
||||
|
@ -11,8 +11,6 @@ use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContex
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use std::ptr;
|
||||
|
||||
use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
|
||||
use crate::late::{
|
||||
ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind,
|
||||
@ -20,7 +18,7 @@ use crate::late::{
|
||||
use crate::macros::{sub_namespace_match, MacroRulesScope};
|
||||
use crate::BindingKey;
|
||||
use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
|
||||
use crate::{Import, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot};
|
||||
use crate::{ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot};
|
||||
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res};
|
||||
use crate::{ResolutionError, Resolver, Scope, ScopeSet, Segment, ToNameBinding, Weak};
|
||||
|
||||
@ -284,7 +282,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
parent_scope: &ParentScope<'a>,
|
||||
finalize: Option<Finalize>,
|
||||
ribs: &[Rib<'a>],
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> Option<LexicalScopeBinding<'a>> {
|
||||
assert!(ns == TypeNS || ns == ValueNS);
|
||||
let orig_ident = ident;
|
||||
@ -378,8 +376,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
parent_scope: &ParentScope<'a>,
|
||||
finalize: Option<Finalize>,
|
||||
force: bool,
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
) -> Result<&'a NameBinding<'a>, Determinacy> {
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> Result<NameBinding<'a>, Determinacy> {
|
||||
bitflags::bitflags! {
|
||||
struct Flags: u8 {
|
||||
const MACRO_RULES = 1 << 0;
|
||||
@ -415,7 +413,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
// }
|
||||
// So we have to save the innermost solution and continue searching in outer scopes
|
||||
// to detect potential ambiguities.
|
||||
let mut innermost_result: Option<(&NameBinding<'_>, Flags)> = None;
|
||||
let mut innermost_result: Option<(NameBinding<'_>, Flags)> = None;
|
||||
let mut determinacy = Determinacy::Determined;
|
||||
|
||||
// Go through all the scopes and try to resolve the name.
|
||||
@ -538,7 +536,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
),
|
||||
);
|
||||
}
|
||||
let misc_flags = if ptr::eq(module, this.graph_root) {
|
||||
let misc_flags = if module == this.graph_root {
|
||||
Flags::MISC_SUGGEST_CRATE
|
||||
} else if module.is_normal() {
|
||||
Flags::MISC_SUGGEST_SELF
|
||||
@ -717,7 +715,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
parent_scope: &ParentScope<'a>,
|
||||
) -> Result<&'a NameBinding<'a>, Determinacy> {
|
||||
) -> Result<NameBinding<'a>, Determinacy> {
|
||||
self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, None, None)
|
||||
.map_err(|(determinacy, _)| determinacy)
|
||||
}
|
||||
@ -730,8 +728,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
ns: Namespace,
|
||||
parent_scope: &ParentScope<'a>,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
) -> Result<&'a NameBinding<'a>, Determinacy> {
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> Result<NameBinding<'a>, Determinacy> {
|
||||
self.resolve_ident_in_module_ext(module, ident, ns, parent_scope, finalize, ignore_binding)
|
||||
.map_err(|(determinacy, _)| determinacy)
|
||||
}
|
||||
@ -744,8 +742,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
ns: Namespace,
|
||||
parent_scope: &ParentScope<'a>,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> {
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> Result<NameBinding<'a>, (Determinacy, Weak)> {
|
||||
let tmp_parent_scope;
|
||||
let mut adjusted_parent_scope = parent_scope;
|
||||
match module {
|
||||
@ -782,8 +780,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
ns: Namespace,
|
||||
parent_scope: &ParentScope<'a>,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
) -> Result<&'a NameBinding<'a>, Determinacy> {
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> Result<NameBinding<'a>, Determinacy> {
|
||||
self.resolve_ident_in_module_unadjusted_ext(
|
||||
module,
|
||||
ident,
|
||||
@ -809,8 +807,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
finalize: Option<Finalize>,
|
||||
// This binding should be ignored during in-module resolution, so that we don't get
|
||||
// "self-confirming" import resolutions during import validation and checking.
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> {
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> Result<NameBinding<'a>, (Determinacy, Weak)> {
|
||||
let module = match module {
|
||||
ModuleOrUniformRoot::Module(module) => module,
|
||||
ModuleOrUniformRoot::CrateRootAndExternPrelude => {
|
||||
@ -873,13 +871,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
// binding if it exists. What we really want here is having two separate scopes in
|
||||
// a module - one for non-globs and one for globs, but until that's done use this
|
||||
// hack to avoid inconsistent resolution ICEs during import validation.
|
||||
let binding =
|
||||
[resolution.binding, resolution.shadowed_glob].into_iter().find_map(|binding| {
|
||||
match (binding, ignore_binding) {
|
||||
(Some(binding), Some(ignored)) if ptr::eq(binding, ignored) => None,
|
||||
_ => binding,
|
||||
}
|
||||
});
|
||||
let binding = [resolution.binding, resolution.shadowed_glob]
|
||||
.into_iter()
|
||||
.find_map(|binding| if binding == ignore_binding { None } else { binding });
|
||||
|
||||
if let Some(Finalize { path_span, report_private, .. }) = finalize {
|
||||
let Some(binding) = binding else {
|
||||
@ -917,11 +911,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
if !restricted_shadowing && binding.expansion != LocalExpnId::ROOT {
|
||||
if let NameBindingKind::Import {
|
||||
import: Import { kind: ImportKind::MacroExport, .. },
|
||||
..
|
||||
} = binding.kind
|
||||
{
|
||||
if let NameBindingKind::Import { import, .. } = binding.kind
|
||||
&& matches!(import.kind, ImportKind::MacroExport) {
|
||||
self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
|
||||
}
|
||||
}
|
||||
@ -930,7 +921,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
return Ok(binding);
|
||||
}
|
||||
|
||||
let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
|
||||
let check_usable = |this: &mut Self, binding: NameBinding<'a>| {
|
||||
let usable = this.is_accessible_from(binding.vis, parent_scope.module);
|
||||
if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
|
||||
};
|
||||
@ -955,7 +946,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
if let Some(ignored) = ignore_binding &&
|
||||
let NameBindingKind::Import { import, .. } = ignored.kind &&
|
||||
ptr::eq(import, &**single_import) {
|
||||
import == *single_import {
|
||||
// Ignore not just the binding itself, but if it has a shadowed_glob,
|
||||
// ignore that, too, because this loop is supposed to only process
|
||||
// named imports.
|
||||
@ -1352,7 +1343,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
opt_ns: Option<Namespace>, // `None` indicates a module path in import
|
||||
parent_scope: &ParentScope<'a>,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> PathResult<'a> {
|
||||
self.resolve_path_with_ribs(path, opt_ns, parent_scope, finalize, None, ignore_binding)
|
||||
}
|
||||
@ -1364,7 +1355,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
parent_scope: &ParentScope<'a>,
|
||||
finalize: Option<Finalize>,
|
||||
ribs: Option<&PerNS<Vec<Rib<'a>>>>,
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> PathResult<'a> {
|
||||
let mut module = None;
|
||||
let mut allow_super = true;
|
||||
|
@ -12,7 +12,7 @@ use crate::{fluent_generated as fluent, Namespace::*};
|
||||
use crate::{module_to_string, names_to_string, ImportSuggestion};
|
||||
use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
|
||||
use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
|
||||
use crate::{NameBinding, NameBindingKind, PathResult};
|
||||
use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult};
|
||||
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
@ -35,7 +35,7 @@ use rustc_span::Span;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::{mem, ptr};
|
||||
use std::mem;
|
||||
|
||||
type Res = def::Res<NodeId>;
|
||||
|
||||
@ -48,9 +48,9 @@ pub(crate) enum ImportKind<'a> {
|
||||
/// `target` in `use prefix::source as target`.
|
||||
target: Ident,
|
||||
/// Bindings to which `source` refers to.
|
||||
source_bindings: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
|
||||
source_bindings: PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>,
|
||||
/// Bindings introduced by `target`.
|
||||
target_bindings: PerNS<Cell<Option<&'a NameBinding<'a>>>>,
|
||||
target_bindings: PerNS<Cell<Option<NameBinding<'a>>>>,
|
||||
/// `true` for `...::{self [as target]}` imports, `false` otherwise.
|
||||
type_ns_only: bool,
|
||||
/// Did this import result from a nested import? ie. `use foo::{bar, baz};`
|
||||
@ -135,7 +135,7 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
|
||||
|
||||
/// One import.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct Import<'a> {
|
||||
pub(crate) struct ImportData<'a> {
|
||||
pub kind: ImportKind<'a>,
|
||||
|
||||
/// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id`
|
||||
@ -172,7 +172,11 @@ pub(crate) struct Import<'a> {
|
||||
pub used: Cell<bool>,
|
||||
}
|
||||
|
||||
impl<'a> Import<'a> {
|
||||
/// All imports are unique and allocated on a same arena,
|
||||
/// so we can use referential equality to compare them.
|
||||
pub(crate) type Import<'a> = Interned<'a, ImportData<'a>>;
|
||||
|
||||
impl<'a> ImportData<'a> {
|
||||
pub(crate) fn is_glob(&self) -> bool {
|
||||
matches!(self.kind, ImportKind::Glob { .. })
|
||||
}
|
||||
@ -214,15 +218,15 @@ impl<'a> Import<'a> {
|
||||
pub(crate) struct NameResolution<'a> {
|
||||
/// Single imports that may define the name in the namespace.
|
||||
/// Imports are arena-allocated, so it's ok to use pointers as keys.
|
||||
pub single_imports: FxHashSet<Interned<'a, Import<'a>>>,
|
||||
pub single_imports: FxHashSet<Import<'a>>,
|
||||
/// The least shadowable known binding for this name, or None if there are no known bindings.
|
||||
pub binding: Option<&'a NameBinding<'a>>,
|
||||
pub shadowed_glob: Option<&'a NameBinding<'a>>,
|
||||
pub binding: Option<NameBinding<'a>>,
|
||||
pub shadowed_glob: Option<NameBinding<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> NameResolution<'a> {
|
||||
/// Returns the binding for the name if it is known or None if it not known.
|
||||
pub(crate) fn binding(&self) -> Option<&'a NameBinding<'a>> {
|
||||
pub(crate) fn binding(&self) -> Option<NameBinding<'a>> {
|
||||
self.binding.and_then(|binding| {
|
||||
if !binding.is_glob_import() || self.single_imports.is_empty() {
|
||||
Some(binding)
|
||||
@ -231,10 +235,6 @@ impl<'a> NameResolution<'a> {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn add_single_import(&mut self, import: &'a Import<'a>) {
|
||||
self.single_imports.insert(Interned::new_unchecked(import));
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
|
||||
@ -250,15 +250,12 @@ struct UnresolvedImportError {
|
||||
|
||||
// Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
|
||||
// are permitted for backward-compatibility under a deprecation lint.
|
||||
fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBinding<'_>) -> bool {
|
||||
fn pub_use_of_private_extern_crate_hack(import: Import<'_>, binding: NameBinding<'_>) -> bool {
|
||||
match (&import.kind, &binding.kind) {
|
||||
(
|
||||
ImportKind::Single { .. },
|
||||
NameBindingKind::Import {
|
||||
import: Import { kind: ImportKind::ExternCrate { .. }, .. },
|
||||
..
|
||||
},
|
||||
) => import.expect_vis().is_public(),
|
||||
(ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. }) => {
|
||||
matches!(binding_import.kind, ImportKind::ExternCrate { .. })
|
||||
&& import.expect_vis().is_public()
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -266,11 +263,7 @@ fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBindi
|
||||
impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
/// Given a binding and an import that resolves to it,
|
||||
/// return the corresponding binding defined by the import.
|
||||
pub(crate) fn import(
|
||||
&self,
|
||||
binding: &'a NameBinding<'a>,
|
||||
import: &'a Import<'a>,
|
||||
) -> &'a NameBinding<'a> {
|
||||
pub(crate) fn import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a> {
|
||||
let import_vis = import.expect_vis().to_def_id();
|
||||
let vis = if binding.vis.is_at_least(import_vis, self.tcx)
|
||||
|| pub_use_of_private_extern_crate_hack(import, binding)
|
||||
@ -288,7 +281,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
self.arenas.alloc_name_binding(NameBinding {
|
||||
self.arenas.alloc_name_binding(NameBindingData {
|
||||
kind: NameBindingKind::Import { binding, import, used: Cell::new(false) },
|
||||
ambiguity: None,
|
||||
span: import.span,
|
||||
@ -302,8 +295,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
&mut self,
|
||||
module: Module<'a>,
|
||||
key: BindingKey,
|
||||
binding: &'a NameBinding<'a>,
|
||||
) -> Result<(), &'a NameBinding<'a>> {
|
||||
binding: NameBinding<'a>,
|
||||
) -> Result<(), NameBinding<'a>> {
|
||||
let res = binding.res();
|
||||
self.check_reserved_macro_name(key.ident, res);
|
||||
self.set_binding_parent_module(binding, module);
|
||||
@ -372,12 +365,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
fn ambiguity(
|
||||
&self,
|
||||
kind: AmbiguityKind,
|
||||
primary_binding: &'a NameBinding<'a>,
|
||||
secondary_binding: &'a NameBinding<'a>,
|
||||
) -> &'a NameBinding<'a> {
|
||||
self.arenas.alloc_name_binding(NameBinding {
|
||||
primary_binding: NameBinding<'a>,
|
||||
secondary_binding: NameBinding<'a>,
|
||||
) -> NameBinding<'a> {
|
||||
self.arenas.alloc_name_binding(NameBindingData {
|
||||
ambiguity: Some((secondary_binding, kind)),
|
||||
..primary_binding.clone()
|
||||
..(*primary_binding).clone()
|
||||
})
|
||||
}
|
||||
|
||||
@ -395,13 +388,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
let t = f(self, resolution);
|
||||
|
||||
match resolution.binding() {
|
||||
_ if old_binding.is_some() => return t,
|
||||
None => return t,
|
||||
Some(binding) => match old_binding {
|
||||
Some(old_binding) if ptr::eq(old_binding, binding) => return t,
|
||||
_ => (binding, t),
|
||||
},
|
||||
if old_binding.is_none() && let Some(binding) = resolution.binding() {
|
||||
(binding, t)
|
||||
} else {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
@ -414,7 +404,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
None => continue,
|
||||
};
|
||||
if self.is_accessible_from(binding.vis, scope) {
|
||||
let imported_binding = self.import(binding, import);
|
||||
let imported_binding = self.import(binding, *import);
|
||||
let key = BindingKey { ident, ..key };
|
||||
let _ = self.try_define(import.parent_scope.module, key, imported_binding);
|
||||
}
|
||||
@ -425,7 +415,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
// Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
|
||||
// or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
|
||||
fn import_dummy_binding(&mut self, import: &'a Import<'a>, is_indeterminate: bool) {
|
||||
fn import_dummy_binding(&mut self, import: Import<'a>, is_indeterminate: bool) {
|
||||
if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
|
||||
if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
|
||||
{
|
||||
@ -463,7 +453,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
prev_indeterminate_count = indeterminate_count;
|
||||
indeterminate_count = 0;
|
||||
for import in mem::take(&mut self.indeterminate_imports) {
|
||||
let import_indeterminate_count = self.resolve_import(&import);
|
||||
let import_indeterminate_count = self.resolve_import(import);
|
||||
indeterminate_count += import_indeterminate_count;
|
||||
match import_indeterminate_count {
|
||||
0 => self.determined_imports.push(import),
|
||||
@ -475,7 +465,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
pub(crate) fn finalize_imports(&mut self) {
|
||||
for module in self.arenas.local_modules().iter() {
|
||||
self.finalize_resolutions_in(module);
|
||||
self.finalize_resolutions_in(*module);
|
||||
}
|
||||
|
||||
let mut seen_spans = FxHashSet::default();
|
||||
@ -546,17 +536,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
pub(crate) fn check_hidden_glob_reexports(
|
||||
&mut self,
|
||||
exported_ambiguities: FxHashSet<Interned<'a, NameBinding<'a>>>,
|
||||
exported_ambiguities: FxHashSet<NameBinding<'a>>,
|
||||
) {
|
||||
for module in self.arenas.local_modules().iter() {
|
||||
for (key, resolution) in self.resolutions(module).borrow().iter() {
|
||||
for (key, resolution) in self.resolutions(*module).borrow().iter() {
|
||||
let resolution = resolution.borrow();
|
||||
|
||||
if let Some(binding) = resolution.binding {
|
||||
if let NameBindingKind::Import { import, .. } = binding.kind
|
||||
&& let Some((amb_binding, _)) = binding.ambiguity
|
||||
&& binding.res() != Res::Err
|
||||
&& exported_ambiguities.contains(&Interned::new_unchecked(binding))
|
||||
&& exported_ambiguities.contains(&binding)
|
||||
{
|
||||
self.lint_buffer.buffer_lint_with_diagnostic(
|
||||
AMBIGUOUS_GLOB_REEXPORTS,
|
||||
@ -612,7 +602,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn throw_unresolved_import_error(&mut self, errors: Vec<(&Import<'_>, UnresolvedImportError)>) {
|
||||
fn throw_unresolved_import_error(&mut self, errors: Vec<(Import<'_>, UnresolvedImportError)>) {
|
||||
if errors.is_empty() {
|
||||
return;
|
||||
}
|
||||
@ -704,7 +694,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
///
|
||||
/// Meanwhile, if resolve successful, the resolved bindings are written
|
||||
/// into the module.
|
||||
fn resolve_import(&mut self, import: &'a Import<'a>) -> usize {
|
||||
fn resolve_import(&mut self, import: Import<'a>) -> usize {
|
||||
debug!(
|
||||
"(resolving import for module) resolving import `{}::...` in `{}`",
|
||||
Segment::names_to_string(&import.module_path),
|
||||
@ -784,7 +774,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
let key = BindingKey::new(target, ns);
|
||||
this.update_resolution(parent, key, |_, resolution| {
|
||||
resolution.single_imports.remove(&Interned::new_unchecked(import));
|
||||
resolution.single_imports.remove(&import);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -798,7 +788,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
///
|
||||
/// Optionally returns an unresolved import error. This error is buffered and used to
|
||||
/// consolidate multiple unresolved import errors into a single diagnostic.
|
||||
fn finalize_import(&mut self, import: &'a Import<'a>) -> Option<UnresolvedImportError> {
|
||||
fn finalize_import(&mut self, import: Import<'a>) -> Option<UnresolvedImportError> {
|
||||
let orig_vis = import.vis.take();
|
||||
let ignore_binding = match &import.kind {
|
||||
ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
|
||||
@ -824,7 +814,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
PathResult::Module(module) => {
|
||||
// Consistency checks, analogous to `finalize_macro_resolutions`.
|
||||
if let Some(initial_module) = import.imported_module.get() {
|
||||
if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity {
|
||||
if module != initial_module && no_ambiguity {
|
||||
span_bug!(import.span, "inconsistent resolution for an import");
|
||||
}
|
||||
} else if self.privacy_errors.is_empty() {
|
||||
@ -926,7 +916,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
if let ModuleOrUniformRoot::Module(module) = module {
|
||||
if ptr::eq(module, import.parent_scope.module) {
|
||||
if module == import.parent_scope.module {
|
||||
// Importing a module into itself is not allowed.
|
||||
return Some(UnresolvedImportError {
|
||||
span: import.span,
|
||||
@ -1242,9 +1232,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
fn check_for_redundant_imports(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
import: &'a Import<'a>,
|
||||
source_bindings: &PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
|
||||
target_bindings: &PerNS<Cell<Option<&'a NameBinding<'a>>>>,
|
||||
import: Import<'a>,
|
||||
source_bindings: &PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>,
|
||||
target_bindings: &PerNS<Cell<Option<NameBinding<'a>>>>,
|
||||
target: Ident,
|
||||
) {
|
||||
// This function is only called for single imports.
|
||||
@ -1305,7 +1295,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_glob_import(&mut self, import: &'a Import<'a>) {
|
||||
fn resolve_glob_import(&mut self, import: Import<'a>) {
|
||||
// This function is only called for glob imports.
|
||||
let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
|
||||
|
||||
@ -1319,7 +1309,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
if module.is_trait() {
|
||||
self.tcx.sess.create_err(ItemsInTraitsAreNotImportable { span: import.span }).emit();
|
||||
return;
|
||||
} else if ptr::eq(module, import.parent_scope.module) {
|
||||
} else if module == import.parent_scope.module {
|
||||
return;
|
||||
} else if is_prelude {
|
||||
self.prelude = Some(module);
|
||||
|
@ -1284,7 +1284,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
finalize: Option<Finalize>,
|
||||
ignore_binding: Option<&'a NameBinding<'a>>,
|
||||
ignore_binding: Option<NameBinding<'a>>,
|
||||
) -> Option<LexicalScopeBinding<'a>> {
|
||||
self.r.resolve_ident_in_lexical_scope(
|
||||
ident,
|
||||
@ -2972,7 +2972,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
F: FnOnce(Ident, String, Option<Symbol>) -> ResolutionError<'a>,
|
||||
{
|
||||
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
|
||||
let Some((module, _)) = &self.current_trait_ref else { return; };
|
||||
let Some((module, _)) = self.current_trait_ref else { return; };
|
||||
ident.span.normalize_to_macros_2_0_and_adjust(module.expansion);
|
||||
let key = BindingKey::new(ident, ns);
|
||||
let mut binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding);
|
||||
|
@ -1593,7 +1593,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||
return None;
|
||||
}
|
||||
|
||||
let resolutions = self.r.resolutions(module);
|
||||
let resolutions = self.r.resolutions(*module);
|
||||
let targets = resolutions
|
||||
.borrow()
|
||||
.iter()
|
||||
|
@ -14,6 +14,7 @@
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(rustdoc::private_intra_doc_links)]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
@ -61,10 +62,10 @@ use rustc_span::{Span, DUMMY_SP};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::BTreeSet;
|
||||
use std::{fmt, ptr};
|
||||
use std::fmt;
|
||||
|
||||
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
|
||||
use imports::{Import, ImportKind, NameResolution};
|
||||
use imports::{Import, ImportData, ImportKind, NameResolution};
|
||||
use late::{HasGenericParams, PathSource, PatternSource};
|
||||
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
|
||||
|
||||
@ -352,7 +353,7 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
|
||||
/// forward.
|
||||
#[derive(Debug)]
|
||||
enum LexicalScopeBinding<'a> {
|
||||
Item(&'a NameBinding<'a>),
|
||||
Item(NameBinding<'a>),
|
||||
Res(Res),
|
||||
}
|
||||
|
||||
@ -365,7 +366,7 @@ impl<'a> LexicalScopeBinding<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
enum ModuleOrUniformRoot<'a> {
|
||||
/// Regular module.
|
||||
Module(Module<'a>),
|
||||
@ -383,23 +384,6 @@ enum ModuleOrUniformRoot<'a> {
|
||||
CurrentScope,
|
||||
}
|
||||
|
||||
impl ModuleOrUniformRoot<'_> {
|
||||
fn same_def(lhs: Self, rhs: Self) -> bool {
|
||||
match (lhs, rhs) {
|
||||
(ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) => {
|
||||
ptr::eq(lhs, rhs)
|
||||
}
|
||||
(
|
||||
ModuleOrUniformRoot::CrateRootAndExternPrelude,
|
||||
ModuleOrUniformRoot::CrateRootAndExternPrelude,
|
||||
)
|
||||
| (ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude)
|
||||
| (ModuleOrUniformRoot::CurrentScope, ModuleOrUniformRoot::CurrentScope) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum PathResult<'a> {
|
||||
Module(ModuleOrUniformRoot<'a>),
|
||||
@ -518,11 +502,11 @@ struct ModuleData<'a> {
|
||||
/// Whether `#[no_implicit_prelude]` is active.
|
||||
no_implicit_prelude: bool,
|
||||
|
||||
glob_importers: RefCell<Vec<&'a Import<'a>>>,
|
||||
globs: RefCell<Vec<&'a Import<'a>>>,
|
||||
glob_importers: RefCell<Vec<Import<'a>>>,
|
||||
globs: RefCell<Vec<Import<'a>>>,
|
||||
|
||||
/// Used to memoize the traits in this module for faster searches through all traits in scope.
|
||||
traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>,
|
||||
traits: RefCell<Option<Box<[(Ident, NameBinding<'a>)]>>>,
|
||||
|
||||
/// Span of the module itself. Used for error reporting.
|
||||
span: Span,
|
||||
@ -530,7 +514,11 @@ struct ModuleData<'a> {
|
||||
expansion: ExpnId,
|
||||
}
|
||||
|
||||
type Module<'a> = &'a 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)]
|
||||
#[rustc_pass_by_value]
|
||||
struct Module<'a>(Interned<'a, ModuleData<'a>>);
|
||||
|
||||
impl<'a> ModuleData<'a> {
|
||||
fn new(
|
||||
@ -558,11 +546,13 @@ impl<'a> ModuleData<'a> {
|
||||
expansion,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn for_each_child<'tcx, R, F>(&'a self, resolver: &mut R, mut f: F)
|
||||
impl<'a> Module<'a> {
|
||||
fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F)
|
||||
where
|
||||
R: AsMut<Resolver<'a, 'tcx>>,
|
||||
F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>),
|
||||
F: FnMut(&mut R, Ident, Namespace, NameBinding<'a>),
|
||||
{
|
||||
for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
|
||||
if let Some(binding) = name_resolution.borrow().binding {
|
||||
@ -572,7 +562,7 @@ impl<'a> ModuleData<'a> {
|
||||
}
|
||||
|
||||
/// This modifies `self` in place. The traits will be stored in `self.traits`.
|
||||
fn ensure_traits<'tcx, R>(&'a self, resolver: &mut R)
|
||||
fn ensure_traits<'tcx, R>(self, resolver: &mut R)
|
||||
where
|
||||
R: AsMut<Resolver<'a, 'tcx>>,
|
||||
{
|
||||
@ -591,7 +581,7 @@ impl<'a> ModuleData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn res(&self) -> Option<Res> {
|
||||
fn res(self) -> Option<Res> {
|
||||
match self.kind {
|
||||
ModuleKind::Def(kind, def_id, _) => Some(Res::Def(kind, def_id)),
|
||||
_ => None,
|
||||
@ -599,11 +589,11 @@ impl<'a> ModuleData<'a> {
|
||||
}
|
||||
|
||||
// Public for rustdoc.
|
||||
fn def_id(&self) -> DefId {
|
||||
fn def_id(self) -> DefId {
|
||||
self.opt_def_id().expect("`ModuleData::def_id` is called on a block module")
|
||||
}
|
||||
|
||||
fn opt_def_id(&self) -> Option<DefId> {
|
||||
fn opt_def_id(self) -> Option<DefId> {
|
||||
match self.kind {
|
||||
ModuleKind::Def(_, def_id, _) => Some(def_id),
|
||||
_ => None,
|
||||
@ -611,15 +601,15 @@ impl<'a> ModuleData<'a> {
|
||||
}
|
||||
|
||||
// `self` resolves to the first module ancestor that `is_normal`.
|
||||
fn is_normal(&self) -> bool {
|
||||
fn is_normal(self) -> bool {
|
||||
matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _))
|
||||
}
|
||||
|
||||
fn is_trait(&self) -> bool {
|
||||
fn is_trait(self) -> bool {
|
||||
matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _))
|
||||
}
|
||||
|
||||
fn nearest_item_scope(&'a self) -> Module<'a> {
|
||||
fn nearest_item_scope(self) -> Module<'a> {
|
||||
match self.kind {
|
||||
ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => {
|
||||
self.parent.expect("enum or trait module without a parent")
|
||||
@ -630,15 +620,15 @@ impl<'a> ModuleData<'a> {
|
||||
|
||||
/// The [`DefId`] of the nearest `mod` item ancestor (which may be this module).
|
||||
/// This may be the crate root.
|
||||
fn nearest_parent_mod(&self) -> DefId {
|
||||
fn nearest_parent_mod(self) -> DefId {
|
||||
match self.kind {
|
||||
ModuleKind::Def(DefKind::Mod, def_id, _) => def_id,
|
||||
_ => self.parent.expect("non-root module without parent").nearest_parent_mod(),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_ancestor_of(&self, mut other: &Self) -> bool {
|
||||
while !ptr::eq(self, other) {
|
||||
fn is_ancestor_of(self, mut other: Self) -> bool {
|
||||
while self != other {
|
||||
if let Some(parent) = other.parent {
|
||||
other = parent;
|
||||
} else {
|
||||
@ -649,7 +639,15 @@ impl<'a> ModuleData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for ModuleData<'a> {
|
||||
impl<'a> std::ops::Deref for Module<'a> {
|
||||
type Target = ModuleData<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for Module<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self.res())
|
||||
}
|
||||
@ -657,20 +655,24 @@ impl<'a> fmt::Debug for ModuleData<'a> {
|
||||
|
||||
/// Records a possibly-private value, type, or module definition.
|
||||
#[derive(Clone, Debug)]
|
||||
struct NameBinding<'a> {
|
||||
struct NameBindingData<'a> {
|
||||
kind: NameBindingKind<'a>,
|
||||
ambiguity: Option<(&'a NameBinding<'a>, AmbiguityKind)>,
|
||||
ambiguity: Option<(NameBinding<'a>, AmbiguityKind)>,
|
||||
expansion: LocalExpnId,
|
||||
span: Span,
|
||||
vis: ty::Visibility<DefId>,
|
||||
}
|
||||
|
||||
/// All name bindings are unique and allocated on a same arena,
|
||||
/// so we can use referential equality to compare them.
|
||||
type NameBinding<'a> = Interned<'a, NameBindingData<'a>>;
|
||||
|
||||
trait ToNameBinding<'a> {
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a>;
|
||||
fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a>;
|
||||
}
|
||||
|
||||
impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> {
|
||||
fn to_name_binding(self, _: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
|
||||
impl<'a> ToNameBinding<'a> for NameBinding<'a> {
|
||||
fn to_name_binding(self, _: &'a ResolverArenas<'a>) -> NameBinding<'a> {
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -679,7 +681,7 @@ impl<'a> ToNameBinding<'a> for &'a NameBinding<'a> {
|
||||
enum NameBindingKind<'a> {
|
||||
Res(Res),
|
||||
Module(Module<'a>),
|
||||
Import { binding: &'a NameBinding<'a>, import: &'a Import<'a>, used: Cell<bool> },
|
||||
Import { binding: NameBinding<'a>, import: Import<'a>, used: Cell<bool> },
|
||||
}
|
||||
|
||||
impl<'a> NameBindingKind<'a> {
|
||||
@ -692,7 +694,7 @@ impl<'a> NameBindingKind<'a> {
|
||||
#[derive(Debug)]
|
||||
struct PrivacyError<'a> {
|
||||
ident: Ident,
|
||||
binding: &'a NameBinding<'a>,
|
||||
binding: NameBinding<'a>,
|
||||
dedup_span: Span,
|
||||
outermost_res: Option<(Res, Ident)>,
|
||||
parent_scope: ParentScope<'a>,
|
||||
@ -761,13 +763,13 @@ enum AmbiguityErrorMisc {
|
||||
struct AmbiguityError<'a> {
|
||||
kind: AmbiguityKind,
|
||||
ident: Ident,
|
||||
b1: &'a NameBinding<'a>,
|
||||
b2: &'a NameBinding<'a>,
|
||||
b1: NameBinding<'a>,
|
||||
b2: NameBinding<'a>,
|
||||
misc1: AmbiguityErrorMisc,
|
||||
misc2: AmbiguityErrorMisc,
|
||||
}
|
||||
|
||||
impl<'a> NameBinding<'a> {
|
||||
impl<'a> NameBindingData<'a> {
|
||||
fn module(&self) -> Option<Module<'a>> {
|
||||
match self.kind {
|
||||
NameBindingKind::Module(module) => Some(module),
|
||||
@ -805,14 +807,12 @@ impl<'a> NameBinding<'a> {
|
||||
|
||||
fn is_extern_crate(&self) -> bool {
|
||||
match self.kind {
|
||||
NameBindingKind::Import {
|
||||
import: &Import { kind: ImportKind::ExternCrate { .. }, .. },
|
||||
..
|
||||
} => true,
|
||||
NameBindingKind::Module(&ModuleData {
|
||||
kind: ModuleKind::Def(DefKind::Mod, def_id, _),
|
||||
..
|
||||
}) => def_id.is_crate_root(),
|
||||
NameBindingKind::Import { import, .. } => {
|
||||
matches!(import.kind, ImportKind::ExternCrate { .. })
|
||||
}
|
||||
NameBindingKind::Module(module)
|
||||
if let ModuleKind::Def(DefKind::Mod, def_id, _) = module.kind
|
||||
=> def_id.is_crate_root(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -855,7 +855,7 @@ impl<'a> NameBinding<'a> {
|
||||
fn may_appear_after(
|
||||
&self,
|
||||
invoc_parent_expansion: LocalExpnId,
|
||||
binding: &NameBinding<'_>,
|
||||
binding: NameBinding<'_>,
|
||||
) -> bool {
|
||||
// self > max(invoc, binding) => !(self <= invoc || self <= binding)
|
||||
// Expansions are partially ordered, so "may appear after" is an inversion of
|
||||
@ -872,7 +872,7 @@ impl<'a> NameBinding<'a> {
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
struct ExternPreludeEntry<'a> {
|
||||
extern_crate_item: Option<&'a NameBinding<'a>>,
|
||||
extern_crate_item: Option<NameBinding<'a>>,
|
||||
introduced_by_item: bool,
|
||||
}
|
||||
|
||||
@ -917,10 +917,10 @@ pub struct Resolver<'a, 'tcx> {
|
||||
field_visibility_spans: FxHashMap<DefId, Vec<Span>>,
|
||||
|
||||
/// All imports known to succeed or fail.
|
||||
determined_imports: Vec<&'a Import<'a>>,
|
||||
determined_imports: Vec<Import<'a>>,
|
||||
|
||||
/// All non-determined imports.
|
||||
indeterminate_imports: Vec<&'a Import<'a>>,
|
||||
indeterminate_imports: Vec<Import<'a>>,
|
||||
|
||||
// Spans for local variables found during pattern resolution.
|
||||
// Used for suggestions during error reporting.
|
||||
@ -962,7 +962,7 @@ pub struct Resolver<'a, 'tcx> {
|
||||
/// language items.
|
||||
empty_module: Module<'a>,
|
||||
module_map: FxHashMap<DefId, Module<'a>>,
|
||||
binding_parent_modules: FxHashMap<Interned<'a, NameBinding<'a>>, Module<'a>>,
|
||||
binding_parent_modules: FxHashMap<NameBinding<'a>, Module<'a>>,
|
||||
|
||||
underscore_disambiguator: u32,
|
||||
|
||||
@ -984,7 +984,7 @@ pub struct Resolver<'a, 'tcx> {
|
||||
macro_expanded_macro_export_errors: BTreeSet<(Span, Span)>,
|
||||
|
||||
arenas: &'a ResolverArenas<'a>,
|
||||
dummy_binding: &'a NameBinding<'a>,
|
||||
dummy_binding: NameBinding<'a>,
|
||||
|
||||
used_extern_options: FxHashSet<Symbol>,
|
||||
macro_names: FxHashSet<Ident>,
|
||||
@ -993,7 +993,7 @@ pub struct Resolver<'a, 'tcx> {
|
||||
/// the surface (`macro` items in libcore), but are actually attributes or derives.
|
||||
builtin_macro_kinds: FxHashMap<LocalDefId, MacroKind>,
|
||||
registered_tools: &'tcx RegisteredTools,
|
||||
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
|
||||
macro_use_prelude: FxHashMap<Symbol, NameBinding<'a>>,
|
||||
macro_map: FxHashMap<DefId, MacroData>,
|
||||
dummy_ext_bang: Lrc<SyntaxExtension>,
|
||||
dummy_ext_derive: Lrc<SyntaxExtension>,
|
||||
@ -1005,7 +1005,7 @@ pub struct Resolver<'a, 'tcx> {
|
||||
proc_macro_stubs: FxHashSet<LocalDefId>,
|
||||
/// Traces collected during macro resolution and validated when it's complete.
|
||||
single_segment_macro_resolutions:
|
||||
Vec<(Ident, MacroKind, ParentScope<'a>, Option<&'a NameBinding<'a>>)>,
|
||||
Vec<(Ident, MacroKind, ParentScope<'a>, Option<NameBinding<'a>>)>,
|
||||
multi_segment_macro_resolutions:
|
||||
Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>, Option<Res>)>,
|
||||
builtin_attrs: Vec<(Ident, ParentScope<'a>)>,
|
||||
@ -1030,7 +1030,7 @@ pub struct Resolver<'a, 'tcx> {
|
||||
/// Avoid duplicated errors for "name already defined".
|
||||
name_already_seen: FxHashMap<Symbol, Span>,
|
||||
|
||||
potentially_unused_imports: Vec<&'a Import<'a>>,
|
||||
potentially_unused_imports: Vec<Import<'a>>,
|
||||
|
||||
/// Table for mapping struct IDs into struct constructor IDs,
|
||||
/// it's not used during normal resolution, only for better error reporting.
|
||||
@ -1085,7 +1085,7 @@ pub struct Resolver<'a, 'tcx> {
|
||||
pub struct ResolverArenas<'a> {
|
||||
modules: TypedArena<ModuleData<'a>>,
|
||||
local_modules: RefCell<Vec<Module<'a>>>,
|
||||
imports: TypedArena<Import<'a>>,
|
||||
imports: TypedArena<ImportData<'a>>,
|
||||
name_resolutions: TypedArena<RefCell<NameResolution<'a>>>,
|
||||
ast_paths: TypedArena<ast::Path>,
|
||||
dropless: DroplessArena,
|
||||
@ -1101,8 +1101,13 @@ impl<'a> ResolverArenas<'a> {
|
||||
no_implicit_prelude: bool,
|
||||
module_map: &mut FxHashMap<DefId, Module<'a>>,
|
||||
) -> Module<'a> {
|
||||
let module =
|
||||
self.modules.alloc(ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude));
|
||||
let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new(
|
||||
parent,
|
||||
kind,
|
||||
expn_id,
|
||||
span,
|
||||
no_implicit_prelude,
|
||||
))));
|
||||
let def_id = module.opt_def_id();
|
||||
if def_id.map_or(true, |def_id| def_id.is_local()) {
|
||||
self.local_modules.borrow_mut().push(module);
|
||||
@ -1115,11 +1120,11 @@ impl<'a> ResolverArenas<'a> {
|
||||
fn local_modules(&'a self) -> std::cell::Ref<'a, Vec<Module<'a>>> {
|
||||
self.local_modules.borrow()
|
||||
}
|
||||
fn alloc_name_binding(&'a self, name_binding: NameBinding<'a>) -> &'a NameBinding<'a> {
|
||||
self.dropless.alloc(name_binding)
|
||||
fn alloc_name_binding(&'a self, name_binding: NameBindingData<'a>) -> NameBinding<'a> {
|
||||
Interned::new_unchecked(self.dropless.alloc(name_binding))
|
||||
}
|
||||
fn alloc_import(&'a self, import: Import<'a>) -> &'a Import<'_> {
|
||||
self.imports.alloc(import)
|
||||
fn alloc_import(&'a self, import: ImportData<'a>) -> Import<'a> {
|
||||
Interned::new_unchecked(self.imports.alloc(import))
|
||||
}
|
||||
fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
|
||||
self.name_resolutions.alloc(Default::default())
|
||||
@ -1314,7 +1319,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
macro_expanded_macro_export_errors: BTreeSet::new(),
|
||||
|
||||
arenas,
|
||||
dummy_binding: arenas.alloc_name_binding(NameBinding {
|
||||
dummy_binding: arenas.alloc_name_binding(NameBindingData {
|
||||
kind: NameBindingKind::Res(Res::Err),
|
||||
ambiguity: None,
|
||||
expansion: LocalExpnId::ROOT,
|
||||
@ -1624,7 +1629,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
self.maybe_unused_trait_imports.insert(def_id);
|
||||
import_ids.push(def_id);
|
||||
}
|
||||
self.add_to_glob_map(&import, trait_name);
|
||||
self.add_to_glob_map(*import, trait_name);
|
||||
kind = &binding.kind;
|
||||
}
|
||||
import_ids
|
||||
@ -1646,7 +1651,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
module.populate_on_access.set(false);
|
||||
self.build_reduced_graph_external(module);
|
||||
}
|
||||
&module.lazy_resolutions
|
||||
&module.0.0.lazy_resolutions
|
||||
}
|
||||
|
||||
fn resolution(
|
||||
@ -1679,12 +1684,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
false
|
||||
}
|
||||
|
||||
fn record_use(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
used_binding: &'a NameBinding<'a>,
|
||||
is_lexical_scope: bool,
|
||||
) {
|
||||
fn record_use(&mut self, ident: Ident, used_binding: NameBinding<'a>, is_lexical_scope: bool) {
|
||||
if let Some((b2, kind)) = used_binding.ambiguity {
|
||||
let ambiguity_error = AmbiguityError {
|
||||
kind,
|
||||
@ -1704,25 +1704,23 @@ 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 let Some(crate_item) = entry.extern_crate_item {
|
||||
if ptr::eq(used_binding, crate_item) && !entry.introduced_by_item {
|
||||
if !entry.introduced_by_item && entry.extern_crate_item == Some(used_binding) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
used.set(true);
|
||||
import.used.set(true);
|
||||
if let Some(id) = import.id() {
|
||||
self.used_imports.insert(id);
|
||||
}
|
||||
self.add_to_glob_map(&import, ident);
|
||||
self.add_to_glob_map(import, ident);
|
||||
self.record_use(ident, binding, false);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) {
|
||||
fn add_to_glob_map(&mut self, import: Import<'_>, ident: Ident) {
|
||||
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);
|
||||
@ -1831,11 +1829,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
vis.is_accessible_from(module.nearest_parent_mod(), self.tcx)
|
||||
}
|
||||
|
||||
fn set_binding_parent_module(&mut self, binding: &'a NameBinding<'a>, module: Module<'a>) {
|
||||
if let Some(old_module) =
|
||||
self.binding_parent_modules.insert(Interned::new_unchecked(binding), module)
|
||||
{
|
||||
if !ptr::eq(module, old_module) {
|
||||
fn set_binding_parent_module(&mut self, binding: NameBinding<'a>, module: Module<'a>) {
|
||||
if let Some(old_module) = self.binding_parent_modules.insert(binding, module) {
|
||||
if module != old_module {
|
||||
span_bug!(binding.span, "parent module is reset for binding");
|
||||
}
|
||||
}
|
||||
@ -1843,25 +1839,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
fn disambiguate_macro_rules_vs_modularized(
|
||||
&self,
|
||||
macro_rules: &'a NameBinding<'a>,
|
||||
modularized: &'a NameBinding<'a>,
|
||||
macro_rules: NameBinding<'a>,
|
||||
modularized: NameBinding<'a>,
|
||||
) -> bool {
|
||||
// Some non-controversial subset of ambiguities "modularized macro name" vs "macro_rules"
|
||||
// is disambiguated to mitigate regressions from macro modularization.
|
||||
// Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
|
||||
match (
|
||||
self.binding_parent_modules.get(&Interned::new_unchecked(macro_rules)),
|
||||
self.binding_parent_modules.get(&Interned::new_unchecked(modularized)),
|
||||
self.binding_parent_modules.get(¯o_rules),
|
||||
self.binding_parent_modules.get(&modularized),
|
||||
) {
|
||||
(Some(macro_rules), Some(modularized)) => {
|
||||
macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
|
||||
&& modularized.is_ancestor_of(macro_rules)
|
||||
&& modularized.is_ancestor_of(*macro_rules)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<&'a NameBinding<'a>> {
|
||||
fn extern_prelude_get(&mut self, ident: Ident, finalize: bool) -> Option<NameBinding<'a>> {
|
||||
if ident.is_path_segment_keyword() {
|
||||
// Make sure `self`, `super` etc produce an error when passed to here.
|
||||
return None;
|
||||
|
@ -42,7 +42,7 @@ type Res = def::Res<NodeId>;
|
||||
/// Not modularized, can shadow previous `macro_rules` bindings, etc.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct MacroRulesBinding<'a> {
|
||||
pub(crate) binding: &'a NameBinding<'a>,
|
||||
pub(crate) binding: NameBinding<'a>,
|
||||
/// `macro_rules` scope into which the `macro_rules` item was planted.
|
||||
pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'a>,
|
||||
pub(crate) ident: Ident,
|
||||
@ -870,7 +870,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
|
||||
fn prohibit_imported_non_macro_attrs(
|
||||
&self,
|
||||
binding: Option<&'a NameBinding<'a>>,
|
||||
binding: Option<NameBinding<'a>>,
|
||||
res: Option<Res>,
|
||||
span: Span,
|
||||
) {
|
||||
|
Loading…
Reference in New Issue
Block a user