resolve: Use Interned for NameBinding

This commit is contained in:
Vadim Petrochenkov 2023-07-04 17:28:57 +03:00
parent 6dab6dc5fc
commit 8efd9cc30d
8 changed files with 106 additions and 124 deletions

View File

@ -9,7 +9,7 @@ use crate::def_collector::collect_definitions;
use crate::imports::{Import, 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};
@ -38,8 +38,8 @@ 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 +50,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 +71,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);
}
}
@ -996,7 +996,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,
) {

View File

@ -182,13 +182,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 +262,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)
};
@ -455,7 +455,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;
@ -1515,7 +1515,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 +1555,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 +1595,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 +1622,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 +1702,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 " },
@ -1762,7 +1762,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,

View File

@ -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);

View File

@ -284,7 +284,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 +378,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 +415,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.
@ -717,7 +717,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 +730,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 +744,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 +782,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 +809,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 +873,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 {
@ -930,7 +926,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)) }
};
@ -1352,7 +1348,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 +1360,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;

View File

@ -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;
@ -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};`
@ -216,13 +216,13 @@ pub(crate) struct NameResolution<'a> {
/// Imports are arena-allocated, so it's ok to use pointers as keys.
pub single_imports: FxHashSet<Interned<'a, 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)
@ -250,7 +250,7 @@ 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 { .. },
@ -268,9 +268,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// return the corresponding binding defined by the import.
pub(crate) fn import(
&self,
binding: &'a NameBinding<'a>,
binding: NameBinding<'a>,
import: &'a Import<'a>,
) -> &'a NameBinding<'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 +288,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 +302,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 +372,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 +395,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;
}
};
@ -546,7 +543,7 @@ 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() {
@ -556,7 +553,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
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,
@ -1243,8 +1240,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&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>>>>,
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.

View File

@ -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,

View File

@ -352,7 +352,7 @@ impl<'a> From<&'a ast::PathSegment> for Segment {
/// forward.
#[derive(Debug)]
enum LexicalScopeBinding<'a> {
Item(&'a NameBinding<'a>),
Item(NameBinding<'a>),
Res(Res),
}
@ -522,7 +522,7 @@ struct ModuleData<'a> {
globs: RefCell<Vec<&'a 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,
@ -562,7 +562,7 @@ impl<'a> ModuleData<'a> {
fn for_each_child<'tcx, R, F>(&'a 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 {
@ -657,20 +657,22 @@ 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>,
}
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: &'a 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),
@ -855,7 +857,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 +874,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,
}
@ -962,7 +964,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 +986,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 +995,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 +1007,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>)>,
@ -1115,8 +1117,8 @@ 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)
@ -1314,7 +1316,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,
@ -1679,12 +1681,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,10 +1701,8 @@ 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 {
return;
}
if !entry.introduced_by_item && entry.extern_crate_item == Some(used_binding) {
return;
}
}
}
@ -1831,10 +1826,8 @@ 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)
{
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 !ptr::eq(module, old_module) {
span_bug!(binding.span, "parent module is reset for binding");
}
@ -1843,15 +1836,15 @@ 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(&macro_rules),
self.binding_parent_modules.get(&modularized),
) {
(Some(macro_rules), Some(modularized)) => {
macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod()
@ -1861,7 +1854,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
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;

View File

@ -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,
) {