From 8efd9cc30dd04cb4e58d9c0420f9ae88e5850f4e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 4 Jul 2023 17:28:57 +0300 Subject: [PATCH 1/4] resolve: Use `Interned` for `NameBinding` --- .../rustc_resolve/src/build_reduced_graph.rs | 14 ++-- compiler/rustc_resolve/src/diagnostics.rs | 22 +++--- .../src/effective_visibilities.rs | 18 ++--- compiler/rustc_resolve/src/ident.rs | 42 +++++------ compiler/rustc_resolve/src/imports.rs | 53 +++++++------ compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 75 +++++++++---------- compiler/rustc_resolve/src/macros.rs | 4 +- 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; impl<'a, Id: Into> ToNameBinding<'a> for (Module<'a>, ty::Visibility, 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> ToNameBinding<'a> } impl<'a, Id: Into> ToNameBinding<'a> for (Res, ty::Visibility, 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, path: &[Segment], - second_binding: Option<&NameBinding<'_>>, + second_binding: Option>, ) { 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 { + fn ctor_fields_span(&self, binding: NameBinding<'_>) -> Option { 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, // `None` indicates a module path in import parent_scope: &ParentScope<'a>, ribs: Option<&PerNS>>>, - ignore_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option>, module: Option>, 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>, + import_effective_visibilities: EffectiveVisibilities>, // 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>> { + ) -> FxHashSet> { 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, ribs: &[Rib<'a>], - ignore_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option>, ) -> Option> { 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, force: bool, - ignore_binding: Option<&'a NameBinding<'a>>, - ) -> Result<&'a NameBinding<'a>, Determinacy> { + ignore_binding: Option>, + ) -> Result, 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, 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, - ignore_binding: Option<&'a NameBinding<'a>>, - ) -> Result<&'a NameBinding<'a>, Determinacy> { + ignore_binding: Option>, + ) -> Result, 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, - ignore_binding: Option<&'a NameBinding<'a>>, - ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { + ignore_binding: Option>, + ) -> Result, (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, - ignore_binding: Option<&'a NameBinding<'a>>, - ) -> Result<&'a NameBinding<'a>, Determinacy> { + ignore_binding: Option>, + ) -> Result, Determinacy> { self.resolve_ident_in_module_unadjusted_ext( module, ident, @@ -809,8 +809,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { finalize: Option, // 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>, + ) -> Result, (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, // `None` indicates a module path in import parent_scope: &ParentScope<'a>, finalize: Option, - ignore_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option>, ) -> 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, ribs: Option<&PerNS>>>, - ignore_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option>, ) -> 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, Determinacy>>>, + source_bindings: PerNS, Determinacy>>>, /// Bindings introduced by `target`. - target_bindings: PerNS>>>, + target_bindings: PerNS>>>, /// `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>>, /// 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>, + pub shadowed_glob: Option>, } 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> { 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>>, + exported_ambiguities: FxHashSet>, ) { 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, Determinacy>>>, - target_bindings: &PerNS>>>, + source_bindings: &PerNS, Determinacy>>>, + target_bindings: &PerNS>>>, 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, - ignore_binding: Option<&'a NameBinding<'a>>, + ignore_binding: Option>, ) -> Option> { 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>>, /// Used to memoize the traits in this module for faster searches through all traits in scope. - traits: RefCell)]>>>, + traits: RefCell)]>>>, /// 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>, - 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, } +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 }, + Import { binding: NameBinding<'a>, import: &'a Import<'a>, used: Cell }, } 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> { 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>, introduced_by_item: bool, } @@ -962,7 +964,7 @@ pub struct Resolver<'a, 'tcx> { /// language items. empty_module: Module<'a>, module_map: FxHashMap>, - binding_parent_modules: FxHashMap>, Module<'a>>, + binding_parent_modules: FxHashMap, 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, macro_names: FxHashSet, @@ -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, registered_tools: &'tcx RegisteredTools, - macro_use_prelude: FxHashMap>, + macro_use_prelude: FxHashMap>, macro_map: FxHashMap, dummy_ext_bang: Lrc, dummy_ext_derive: Lrc, @@ -1005,7 +1007,7 @@ pub struct Resolver<'a, 'tcx> { proc_macro_stubs: FxHashSet, /// 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>)>, multi_segment_macro_resolutions: Vec<(Vec, Span, MacroKind, ParentScope<'a>, Option)>, builtin_attrs: Vec<(Ident, ParentScope<'a>)>, @@ -1115,8 +1117,8 @@ impl<'a> ResolverArenas<'a> { fn local_modules(&'a self) -> std::cell::Ref<'a, Vec>> { 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> { 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; /// 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>, res: Option, span: Span, ) { From 4abdaeb67eb3aa85941cee4928b75dbcbd120148 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 4 Jul 2023 18:51:35 +0300 Subject: [PATCH 2/4] resolve: Use `Interned` for `Import` --- .../rustc_resolve/src/build_reduced_graph.rs | 12 ++--- compiler/rustc_resolve/src/diagnostics.rs | 24 ++++----- compiler/rustc_resolve/src/ident.rs | 11 ++--- compiler/rustc_resolve/src/imports.rs | 49 ++++++++----------- compiler/rustc_resolve/src/lib.rs | 33 ++++++------- 5 files changed, 58 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 9af06f1a48a..fdf1e281b0b 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -6,7 +6,7 @@ //! Imports are also considered items and placed into modules here, but not resolved yet. use crate::def_collector::collect_definitions; -use crate::imports::{Import, ImportKind}; +use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use crate::Namespace::{self, MacroNS, TypeNS, ValueNS}; use crate::{errors, BindingKey, MacroData, NameBindingData}; @@ -354,7 +354,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { vis: ty::Visibility, ) { let current_module = self.parent_scope.module; - let import = self.r.arenas.alloc_import(Import { + let import = self.r.arenas.alloc_import(ImportData { kind, parent_scope: self.parent_scope, module_path, @@ -378,7 +378,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { if !type_ns_only || ns == TypeNS { let key = BindingKey::new(target, ns); let mut resolution = this.resolution(current_module, key).borrow_mut(); - resolution.add_single_import(import); + resolution.single_imports.insert(import); } }); } @@ -848,7 +848,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { (used, Some(ModuleOrUniformRoot::Module(module)), binding) }) .unwrap_or((true, None, self.r.dummy_binding)); - let import = self.r.arenas.alloc_import(Import { + let import = self.r.arenas.alloc_import(ImportData { kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id }, root_id: item.id, parent_scope: self.parent_scope, @@ -1058,7 +1058,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } let macro_use_import = |this: &Self, span| { - this.r.arenas.alloc_import(Import { + this.r.arenas.alloc_import(ImportData { kind: ImportKind::MacroUse, root_id: item.id, parent_scope: this.parent_scope, @@ -1228,7 +1228,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { self.r.set_binding_parent_module(binding, parent_scope.module); self.r.all_macro_rules.insert(ident.name, res); if is_macro_export { - let import = self.r.arenas.alloc_import(Import { + let import = self.r.arenas.alloc_import(ImportData { kind: ImportKind::MacroExport, root_id: item.id, parent_scope: self.parent_scope, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 4db4108c6f4..9c1d4251465 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -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) }; @@ -272,22 +272,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { (Import { import: new, .. }, Import { import: old, .. }) if { (new.has_attributes || old.has_attributes) - && can_suggest(old_binding, old) - && can_suggest(new_binding, new) + && can_suggest(old_binding, *old) + && can_suggest(new_binding, *new) } => { if old.has_attributes { - Some((new, new_binding.span, true)) + Some((*new, new_binding.span, true)) } else { - Some((old, old_binding.span, true)) + Some((*old, old_binding.span, true)) } } // Otherwise prioritize the new binding. - (Import { import, .. }, other) if can_suggest(new_binding, import) => { - Some((import, new_binding.span, other.is_import())) + (Import { import, .. }, other) if can_suggest(new_binding, *import) => { + Some((*import, new_binding.span, other.is_import())) } - (other, Import { import, .. }) if can_suggest(old_binding, import) => { - Some((import, old_binding.span, other.is_import())) + (other, Import { import, .. }) if can_suggest(old_binding, *import) => { + Some((*import, old_binding.span, other.is_import())) } _ => None, }; @@ -341,7 +341,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { &self, err: &mut Diagnostic, name: Symbol, - import: &Import<'_>, + import: Import<'_>, binding_span: Span, ) { let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() { @@ -413,7 +413,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn add_suggestion_for_duplicate_nested_use( &self, err: &mut Diagnostic, - import: &Import<'_>, + import: Import<'_>, binding_span: Span, ) { assert!(import.is_nested()); @@ -2114,7 +2114,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// ``` pub(crate) fn check_for_module_export_macro( &mut self, - import: &'a Import<'a>, + import: Import<'a>, module: ModuleOrUniformRoot<'a>, ident: Ident, ) -> Option<(Option, Option)> { diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index ba6f50ef1ba..40eee48e475 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -20,7 +20,7 @@ use crate::late::{ use crate::macros::{sub_namespace_match, MacroRulesScope}; use crate::BindingKey; use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize}; -use crate::{Import, ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot}; +use crate::{ImportKind, LexicalScopeBinding, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PrivacyError, Res}; use crate::{ResolutionError, Resolver, Scope, ScopeSet, Segment, ToNameBinding, Weak}; @@ -913,11 +913,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } if !restricted_shadowing && binding.expansion != LocalExpnId::ROOT { - if let NameBindingKind::Import { - import: Import { kind: ImportKind::MacroExport, .. }, - .. - } = binding.kind - { + if let NameBindingKind::Import { import, .. } = binding.kind + && matches!(import.kind, ImportKind::MacroExport) { self.macro_expanded_macro_export_errors.insert((path_span, binding.span)); } } @@ -951,7 +948,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } if let Some(ignored) = ignore_binding && let NameBindingKind::Import { import, .. } = ignored.kind && - ptr::eq(import, &**single_import) { + import == *single_import { // Ignore not just the binding itself, but if it has a shadowed_glob, // ignore that, too, because this loop is supposed to only process // named imports. diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 5f5b49d8564..fa8c15abc4b 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -135,7 +135,7 @@ impl<'a> std::fmt::Debug for ImportKind<'a> { /// One import. #[derive(Debug, Clone)] -pub(crate) struct Import<'a> { +pub(crate) struct ImportData<'a> { pub kind: ImportKind<'a>, /// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id` @@ -172,7 +172,9 @@ pub(crate) struct Import<'a> { pub used: Cell, } -impl<'a> Import<'a> { +pub(crate) type Import<'a> = Interned<'a, ImportData<'a>>; + +impl<'a> ImportData<'a> { pub(crate) fn is_glob(&self) -> bool { matches!(self.kind, ImportKind::Glob { .. }) } @@ -214,7 +216,7 @@ impl<'a> Import<'a> { pub(crate) struct NameResolution<'a> { /// Single imports that may define the name in the namespace. /// Imports are arena-allocated, so it's ok to use pointers as keys. - pub single_imports: FxHashSet>>, + pub single_imports: FxHashSet>, /// The least shadowable known binding for this name, or None if there are no known bindings. pub binding: Option>, pub shadowed_glob: Option>, @@ -231,10 +233,6 @@ impl<'a> NameResolution<'a> { } }) } - - pub(crate) fn add_single_import(&mut self, import: &'a Import<'a>) { - self.single_imports.insert(Interned::new_unchecked(import)); - } } /// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved @@ -250,15 +248,12 @@ struct UnresolvedImportError { // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;` // are permitted for backward-compatibility under a deprecation lint. -fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: NameBinding<'_>) -> bool { +fn pub_use_of_private_extern_crate_hack(import: Import<'_>, binding: NameBinding<'_>) -> bool { match (&import.kind, &binding.kind) { - ( - ImportKind::Single { .. }, - NameBindingKind::Import { - import: Import { kind: ImportKind::ExternCrate { .. }, .. }, - .. - }, - ) => import.expect_vis().is_public(), + (ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. }) => { + matches!(binding_import.kind, ImportKind::ExternCrate { .. }) + && import.expect_vis().is_public() + } _ => false, } } @@ -266,11 +261,7 @@ fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: NameBindin impl<'a, 'tcx> Resolver<'a, 'tcx> { /// Given a binding and an import that resolves to it, /// return the corresponding binding defined by the import. - pub(crate) fn import( - &self, - binding: NameBinding<'a>, - import: &'a Import<'a>, - ) -> NameBinding<'a> { + pub(crate) fn import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a> { let import_vis = import.expect_vis().to_def_id(); let vis = if binding.vis.is_at_least(import_vis, self.tcx) || pub_use_of_private_extern_crate_hack(import, binding) @@ -411,7 +402,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { None => continue, }; if self.is_accessible_from(binding.vis, scope) { - let imported_binding = self.import(binding, import); + let imported_binding = self.import(binding, *import); let key = BindingKey { ident, ..key }; let _ = self.try_define(import.parent_scope.module, key, imported_binding); } @@ -422,7 +413,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics. - fn import_dummy_binding(&mut self, import: &'a Import<'a>, is_indeterminate: bool) { + fn import_dummy_binding(&mut self, import: Import<'a>, is_indeterminate: bool) { if let ImportKind::Single { target, ref target_bindings, .. } = import.kind { if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none())) { @@ -460,7 +451,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { prev_indeterminate_count = indeterminate_count; indeterminate_count = 0; for import in mem::take(&mut self.indeterminate_imports) { - let import_indeterminate_count = self.resolve_import(&import); + let import_indeterminate_count = self.resolve_import(import); indeterminate_count += import_indeterminate_count; match import_indeterminate_count { 0 => self.determined_imports.push(import), @@ -609,7 +600,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn throw_unresolved_import_error(&mut self, errors: Vec<(&Import<'_>, UnresolvedImportError)>) { + fn throw_unresolved_import_error(&mut self, errors: Vec<(Import<'_>, UnresolvedImportError)>) { if errors.is_empty() { return; } @@ -701,7 +692,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// /// Meanwhile, if resolve successful, the resolved bindings are written /// into the module. - fn resolve_import(&mut self, import: &'a Import<'a>) -> usize { + fn resolve_import(&mut self, import: Import<'a>) -> usize { debug!( "(resolving import for module) resolving import `{}::...` in `{}`", Segment::names_to_string(&import.module_path), @@ -781,7 +772,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } let key = BindingKey::new(target, ns); this.update_resolution(parent, key, |_, resolution| { - resolution.single_imports.remove(&Interned::new_unchecked(import)); + resolution.single_imports.remove(&import); }); } } @@ -795,7 +786,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// /// Optionally returns an unresolved import error. This error is buffered and used to /// consolidate multiple unresolved import errors into a single diagnostic. - fn finalize_import(&mut self, import: &'a Import<'a>) -> Option { + fn finalize_import(&mut self, import: Import<'a>) -> Option { let orig_vis = import.vis.take(); let ignore_binding = match &import.kind { ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(), @@ -1239,7 +1230,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn check_for_redundant_imports( &mut self, ident: Ident, - import: &'a Import<'a>, + import: Import<'a>, source_bindings: &PerNS, Determinacy>>>, target_bindings: &PerNS>>>, target: Ident, @@ -1302,7 +1293,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn resolve_glob_import(&mut self, import: &'a Import<'a>) { + fn resolve_glob_import(&mut self, import: Import<'a>) { // This function is only called for glob imports. let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() }; diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 8fefbe8177e..8ee0c715a0e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -64,7 +64,7 @@ use std::collections::BTreeSet; use std::{fmt, ptr}; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; -use imports::{Import, ImportKind, NameResolution}; +use imports::{Import, ImportData, ImportKind, NameResolution}; use late::{HasGenericParams, PathSource, PatternSource}; use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; @@ -518,8 +518,8 @@ struct ModuleData<'a> { /// Whether `#[no_implicit_prelude]` is active. no_implicit_prelude: bool, - glob_importers: RefCell>>, - globs: RefCell>>, + glob_importers: RefCell>>, + globs: RefCell>>, /// Used to memoize the traits in this module for faster searches through all traits in scope. traits: RefCell)]>>>, @@ -681,7 +681,7 @@ impl<'a> ToNameBinding<'a> for NameBinding<'a> { enum NameBindingKind<'a> { Res(Res), Module(Module<'a>), - Import { binding: NameBinding<'a>, import: &'a Import<'a>, used: Cell }, + Import { binding: NameBinding<'a>, import: Import<'a>, used: Cell }, } impl<'a> NameBindingKind<'a> { @@ -807,10 +807,9 @@ impl<'a> NameBindingData<'a> { fn is_extern_crate(&self) -> bool { match self.kind { - NameBindingKind::Import { - import: &Import { kind: ImportKind::ExternCrate { .. }, .. }, - .. - } => true, + NameBindingKind::Import { import, .. } => { + matches!(import.kind, ImportKind::ExternCrate { .. }) + } NameBindingKind::Module(&ModuleData { kind: ModuleKind::Def(DefKind::Mod, def_id, _), .. @@ -919,10 +918,10 @@ pub struct Resolver<'a, 'tcx> { field_visibility_spans: FxHashMap>, /// All imports known to succeed or fail. - determined_imports: Vec<&'a Import<'a>>, + determined_imports: Vec>, /// All non-determined imports. - indeterminate_imports: Vec<&'a Import<'a>>, + indeterminate_imports: Vec>, // Spans for local variables found during pattern resolution. // Used for suggestions during error reporting. @@ -1032,7 +1031,7 @@ pub struct Resolver<'a, 'tcx> { /// Avoid duplicated errors for "name already defined". name_already_seen: FxHashMap, - potentially_unused_imports: Vec<&'a Import<'a>>, + potentially_unused_imports: Vec>, /// Table for mapping struct IDs into struct constructor IDs, /// it's not used during normal resolution, only for better error reporting. @@ -1087,7 +1086,7 @@ pub struct Resolver<'a, 'tcx> { pub struct ResolverArenas<'a> { modules: TypedArena>, local_modules: RefCell>>, - imports: TypedArena>, + imports: TypedArena>, name_resolutions: TypedArena>>, ast_paths: TypedArena, dropless: DroplessArena, @@ -1120,8 +1119,8 @@ impl<'a> ResolverArenas<'a> { fn alloc_name_binding(&'a self, name_binding: NameBindingData<'a>) -> NameBinding<'a> { Interned::new_unchecked(self.dropless.alloc(name_binding)) } - fn alloc_import(&'a self, import: Import<'a>) -> &'a Import<'_> { - self.imports.alloc(import) + fn alloc_import(&'a self, import: ImportData<'a>) -> Import<'a> { + Interned::new_unchecked(self.imports.alloc(import)) } fn alloc_name_resolution(&'a self) -> &'a RefCell> { self.name_resolutions.alloc(Default::default()) @@ -1626,7 +1625,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.maybe_unused_trait_imports.insert(def_id); import_ids.push(def_id); } - self.add_to_glob_map(&import, trait_name); + self.add_to_glob_map(*import, trait_name); kind = &binding.kind; } import_ids @@ -1711,13 +1710,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(id) = import.id() { self.used_imports.insert(id); } - self.add_to_glob_map(&import, ident); + self.add_to_glob_map(import, ident); self.record_use(ident, binding, false); } } #[inline] - fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) { + fn add_to_glob_map(&mut self, import: Import<'_>, ident: Ident) { if let ImportKind::Glob { id, .. } = import.kind { let def_id = self.local_def_id(id); self.glob_map.entry(def_id).or_default().insert(ident.name); From c1f412f9a93cee5bfd4c4cbdf0e0cb78fc51da2c Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 4 Jul 2023 20:00:42 +0300 Subject: [PATCH 3/4] resolve: Use `Interned` for `Module` --- .../rustc_resolve/src/build_reduced_graph.rs | 7 +- compiler/rustc_resolve/src/diagnostics.rs | 15 ++-- compiler/rustc_resolve/src/ident.rs | 4 +- compiler/rustc_resolve/src/imports.rs | 12 +-- compiler/rustc_resolve/src/late.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 82 +++++++++---------- 7 files changed, 59 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index fdf1e281b0b..e6ceedddfa1 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -31,7 +31,6 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; use std::cell::Cell; -use std::ptr; type Res = def::Res; @@ -142,8 +141,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(def_id) => self.macro_def_scope(def_id), None => expn_id .as_local() - .and_then(|expn_id| self.ast_transform_scopes.get(&expn_id)) - .unwrap_or(&self.graph_root), + .and_then(|expn_id| self.ast_transform_scopes.get(&expn_id).copied()) + .unwrap_or(self.graph_root), } } @@ -864,7 +863,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { }); self.r.potentially_unused_imports.push(import); let imported_binding = self.r.import(binding, import); - if ptr::eq(parent, self.r.graph_root) { + if parent == self.r.graph_root { if let Some(entry) = self.r.extern_prelude.get(&ident.normalize_to_macros_2_0()) { if expansion != LocalExpnId::ROOT && orig_name.is_some() diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9c1d4251465..d3dcdfa4275 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1,5 +1,3 @@ -use std::ptr; - use rustc_ast::expand::StrippedCfgItem; use rustc_ast::ptr::P; use rustc_ast::visit::{self, Visitor}; @@ -1198,7 +1196,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // avoid suggesting anything with a hygienic name if ident.name == lookup_ident.name && ns == namespace - && !ptr::eq(in_module, parent_scope.module) + && in_module != parent_scope.module && !ident.span.normalize_to_macros_2_0().from_expansion() { let res = name_binding.res(); @@ -1732,7 +1730,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pub(crate) fn find_similarly_named_module_or_crate( &mut self, ident: Symbol, - current_module: &Module<'a>, + current_module: Module<'a>, ) -> Option { let mut candidates = self .extern_prelude @@ -1742,7 +1740,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.module_map .iter() .filter(|(_, module)| { - current_module.is_ancestor_of(module) && !ptr::eq(current_module, *module) + current_module.is_ancestor_of(**module) && current_module != **module }) .flat_map(|(_, module)| module.kind.name()), ) @@ -1945,7 +1943,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } suggestion = suggestion.or_else(|| { - self.find_similarly_named_module_or_crate(ident.name, &parent_scope.module).map( + self.find_similarly_named_module_or_crate(ident.name, parent_scope.module).map( |sugg| { ( vec![(ident.span, sugg.to_string())], @@ -2126,9 +2124,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { crate_module = parent; } - if ModuleOrUniformRoot::same_def(ModuleOrUniformRoot::Module(crate_module), module) { - // Don't make a suggestion if the import was already from the root of the - // crate. + if module == ModuleOrUniformRoot::Module(crate_module) { + // Don't make a suggestion if the import was already from the root of the crate. return None; } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 40eee48e475..520fab1f0c8 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -11,8 +11,6 @@ use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContex use rustc_span::symbol::{kw, Ident}; use rustc_span::{Span, DUMMY_SP}; -use std::ptr; - use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst}; use crate::late::{ ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind, @@ -538,7 +536,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ), ); } - let misc_flags = if ptr::eq(module, this.graph_root) { + let misc_flags = if module == this.graph_root { Flags::MISC_SUGGEST_CRATE } else if module.is_normal() { Flags::MISC_SUGGEST_SELF diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index fa8c15abc4b..036fbf2dbf0 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -35,7 +35,7 @@ use rustc_span::Span; use smallvec::SmallVec; use std::cell::Cell; -use std::{mem, ptr}; +use std::mem; type Res = def::Res; @@ -463,7 +463,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pub(crate) fn finalize_imports(&mut self) { for module in self.arenas.local_modules().iter() { - self.finalize_resolutions_in(module); + self.finalize_resolutions_in(*module); } let mut seen_spans = FxHashSet::default(); @@ -537,7 +537,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { exported_ambiguities: FxHashSet>, ) { for module in self.arenas.local_modules().iter() { - for (key, resolution) in self.resolutions(module).borrow().iter() { + for (key, resolution) in self.resolutions(*module).borrow().iter() { let resolution = resolution.borrow(); if let Some(binding) = resolution.binding { @@ -812,7 +812,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { PathResult::Module(module) => { // Consistency checks, analogous to `finalize_macro_resolutions`. if let Some(initial_module) = import.imported_module.get() { - if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity { + if module != initial_module && no_ambiguity { span_bug!(import.span, "inconsistent resolution for an import"); } } else if self.privacy_errors.is_empty() { @@ -914,7 +914,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } if let ModuleOrUniformRoot::Module(module) = module { - if ptr::eq(module, import.parent_scope.module) { + if module == import.parent_scope.module { // Importing a module into itself is not allowed. return Some(UnresolvedImportError { span: import.span, @@ -1307,7 +1307,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if module.is_trait() { self.tcx.sess.create_err(ItemsInTraitsAreNotImportable { span: import.span }).emit(); return; - } else if ptr::eq(module, import.parent_scope.module) { + } else if module == import.parent_scope.module { return; } else if is_prelude { self.prelude = Some(module); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 735a499ff68..90cb312edd2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2972,7 +2972,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { F: FnOnce(Ident, String, Option) -> ResolutionError<'a>, { // If there is a TraitRef in scope for an impl, then the method must be in the trait. - let Some((module, _)) = &self.current_trait_ref else { return; }; + let Some((module, _)) = self.current_trait_ref else { return; }; ident.span.normalize_to_macros_2_0_and_adjust(module.expansion); let key = BindingKey::new(ident, ns); let mut binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 9fec7cc3def..c0e3f1aaf01 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1593,7 +1593,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { return None; } - let resolutions = self.r.resolutions(module); + let resolutions = self.r.resolutions(*module); let targets = resolutions .borrow() .iter() diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 8ee0c715a0e..b6a312c2982 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -14,6 +14,7 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(never_type)] +#![feature(rustc_attrs)] #![recursion_limit = "256"] #![allow(rustdoc::private_intra_doc_links)] #![allow(rustc::potential_query_instability)] @@ -61,7 +62,7 @@ use rustc_span::{Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; use std::cell::{Cell, RefCell}; use std::collections::BTreeSet; -use std::{fmt, ptr}; +use std::fmt; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; use imports::{Import, ImportData, ImportKind, NameResolution}; @@ -365,7 +366,7 @@ impl<'a> LexicalScopeBinding<'a> { } } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, PartialEq, Debug)] enum ModuleOrUniformRoot<'a> { /// Regular module. Module(Module<'a>), @@ -383,23 +384,6 @@ enum ModuleOrUniformRoot<'a> { CurrentScope, } -impl ModuleOrUniformRoot<'_> { - fn same_def(lhs: Self, rhs: Self) -> bool { - match (lhs, rhs) { - (ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) => { - ptr::eq(lhs, rhs) - } - ( - ModuleOrUniformRoot::CrateRootAndExternPrelude, - ModuleOrUniformRoot::CrateRootAndExternPrelude, - ) - | (ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) - | (ModuleOrUniformRoot::CurrentScope, ModuleOrUniformRoot::CurrentScope) => true, - _ => false, - } - } -} - #[derive(Debug)] enum PathResult<'a> { Module(ModuleOrUniformRoot<'a>), @@ -530,7 +514,9 @@ struct ModuleData<'a> { expansion: ExpnId, } -type Module<'a> = &'a ModuleData<'a>; +#[derive(Clone, Copy, PartialEq)] +#[rustc_pass_by_value] +struct Module<'a>(Interned<'a, ModuleData<'a>>); impl<'a> ModuleData<'a> { fn new( @@ -558,8 +544,10 @@ impl<'a> ModuleData<'a> { expansion, } } +} - fn for_each_child<'tcx, R, F>(&'a self, resolver: &mut R, mut f: F) +impl<'a> Module<'a> { + fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F) where R: AsMut>, F: FnMut(&mut R, Ident, Namespace, NameBinding<'a>), @@ -572,7 +560,7 @@ impl<'a> ModuleData<'a> { } /// This modifies `self` in place. The traits will be stored in `self.traits`. - fn ensure_traits<'tcx, R>(&'a self, resolver: &mut R) + fn ensure_traits<'tcx, R>(self, resolver: &mut R) where R: AsMut>, { @@ -591,7 +579,7 @@ impl<'a> ModuleData<'a> { } } - fn res(&self) -> Option { + fn res(self) -> Option { match self.kind { ModuleKind::Def(kind, def_id, _) => Some(Res::Def(kind, def_id)), _ => None, @@ -599,11 +587,11 @@ impl<'a> ModuleData<'a> { } // Public for rustdoc. - fn def_id(&self) -> DefId { + fn def_id(self) -> DefId { self.opt_def_id().expect("`ModuleData::def_id` is called on a block module") } - fn opt_def_id(&self) -> Option { + fn opt_def_id(self) -> Option { match self.kind { ModuleKind::Def(_, def_id, _) => Some(def_id), _ => None, @@ -611,15 +599,15 @@ impl<'a> ModuleData<'a> { } // `self` resolves to the first module ancestor that `is_normal`. - fn is_normal(&self) -> bool { + fn is_normal(self) -> bool { matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _)) } - fn is_trait(&self) -> bool { + fn is_trait(self) -> bool { matches!(self.kind, ModuleKind::Def(DefKind::Trait, _, _)) } - fn nearest_item_scope(&'a self) -> Module<'a> { + fn nearest_item_scope(self) -> Module<'a> { match self.kind { ModuleKind::Def(DefKind::Enum | DefKind::Trait, ..) => { self.parent.expect("enum or trait module without a parent") @@ -630,15 +618,15 @@ impl<'a> ModuleData<'a> { /// The [`DefId`] of the nearest `mod` item ancestor (which may be this module). /// This may be the crate root. - fn nearest_parent_mod(&self) -> DefId { + fn nearest_parent_mod(self) -> DefId { match self.kind { ModuleKind::Def(DefKind::Mod, def_id, _) => def_id, _ => self.parent.expect("non-root module without parent").nearest_parent_mod(), } } - fn is_ancestor_of(&self, mut other: &Self) -> bool { - while !ptr::eq(self, other) { + fn is_ancestor_of(self, mut other: Self) -> bool { + while self != other { if let Some(parent) = other.parent { other = parent; } else { @@ -649,7 +637,15 @@ impl<'a> ModuleData<'a> { } } -impl<'a> fmt::Debug for ModuleData<'a> { +impl<'a> std::ops::Deref for Module<'a> { + type Target = ModuleData<'a>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'a> fmt::Debug for Module<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.res()) } @@ -810,10 +806,9 @@ impl<'a> NameBindingData<'a> { NameBindingKind::Import { import, .. } => { matches!(import.kind, ImportKind::ExternCrate { .. }) } - NameBindingKind::Module(&ModuleData { - kind: ModuleKind::Def(DefKind::Mod, def_id, _), - .. - }) => def_id.is_crate_root(), + NameBindingKind::Module(module) + if let ModuleKind::Def(DefKind::Mod, def_id, _) = module.kind + => def_id.is_crate_root(), _ => false, } } @@ -1102,8 +1097,13 @@ impl<'a> ResolverArenas<'a> { no_implicit_prelude: bool, module_map: &mut FxHashMap>, ) -> Module<'a> { - let module = - self.modules.alloc(ModuleData::new(parent, kind, expn_id, span, no_implicit_prelude)); + let module = Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new( + parent, + kind, + expn_id, + span, + no_implicit_prelude, + )))); let def_id = module.opt_def_id(); if def_id.map_or(true, |def_id| def_id.is_local()) { self.local_modules.borrow_mut().push(module); @@ -1647,7 +1647,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { module.populate_on_access.set(false); self.build_reduced_graph_external(module); } - &module.lazy_resolutions + &module.0.0.lazy_resolutions } fn resolution( @@ -1827,7 +1827,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { 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) { + if module != old_module { span_bug!(binding.span, "parent module is reset for binding"); } } @@ -1847,7 +1847,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ) { (Some(macro_rules), Some(modularized)) => { macro_rules.nearest_parent_mod() == modularized.nearest_parent_mod() - && modularized.is_ancestor_of(macro_rules) + && modularized.is_ancestor_of(*macro_rules) } _ => false, } From 9f3fba8da81300dc1a734a9cb1e2d804286b4f8d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 5 Jul 2023 13:46:42 +0300 Subject: [PATCH 4/4] resolve: Add comments explaining use of `Interned` --- compiler/rustc_resolve/src/imports.rs | 2 ++ compiler/rustc_resolve/src/lib.rs | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 036fbf2dbf0..d37fe783bba 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -172,6 +172,8 @@ pub(crate) struct ImportData<'a> { pub used: Cell, } +/// All imports are unique and allocated on a same arena, +/// so we can use referential equality to compare them. pub(crate) type Import<'a> = Interned<'a, ImportData<'a>>; impl<'a> ImportData<'a> { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b6a312c2982..da3d86a4718 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -514,6 +514,8 @@ struct ModuleData<'a> { expansion: ExpnId, } +/// All modules are unique and allocated on a same arena, +/// so we can use referential equality to compare them. #[derive(Clone, Copy, PartialEq)] #[rustc_pass_by_value] struct Module<'a>(Interned<'a, ModuleData<'a>>); @@ -661,6 +663,8 @@ struct NameBindingData<'a> { vis: ty::Visibility, } +/// All name bindings are unique and allocated on a same arena, +/// so we can use referential equality to compare them. type NameBinding<'a> = Interned<'a, NameBindingData<'a>>; trait ToNameBinding<'a> {