resolve: Use Interned
for NameBinding
This commit is contained in:
parent
6dab6dc5fc
commit
8efd9cc30d
@ -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,
|
||||
) {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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(¯o_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;
|
||||
|
@ -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…
x
Reference in New Issue
Block a user