about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2023-07-04 17:28:57 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2023-07-05 13:47:36 +0300
commit8efd9cc30dd04cb4e58d9c0420f9ae88e5850f4e (patch)
treeba61f5a6a86d3cf592995fa42c74938d2966496a /compiler/rustc_resolve/src
parent6dab6dc5fcd9655adfa7bfb3e59e5cae487184d2 (diff)
downloadrust-8efd9cc30dd04cb4e58d9c0420f9ae88e5850f4e.tar.gz
rust-8efd9cc30dd04cb4e58d9c0420f9ae88e5850f4e.zip
resolve: Use `Interned` for `NameBinding`
Diffstat (limited to 'compiler/rustc_resolve/src')
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs14
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs22
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs18
-rw-r--r--compiler/rustc_resolve/src/ident.rs42
-rw-r--r--compiler/rustc_resolve/src/imports.rs53
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs75
-rw-r--r--compiler/rustc_resolve/src/macros.rs4
8 files changed, 106 insertions, 124 deletions
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 72777733345..9af06f1a48a 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -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,
     ) {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index d9e4974626d..4db4108c6f4 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -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,
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index 4863c9f4790..eb210532f51 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -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);
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 36f01676e7e..ba6f50ef1ba 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -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;
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 074f761c53b..5f5b49d8564 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -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.
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index bca95ce54ad..735a499ff68 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -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,
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index cc4cb9fa30c..8fefbe8177e 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -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;
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index d33e8d40b63..d16b7902f60 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -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,
     ) {