From 30306fdecab6a8d63f3ddc59f119f83b94e65dbb Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Sat, 12 Jul 2025 15:01:39 +0200 Subject: [PATCH 1/8] split up define into define_extern and define_local --- .../rustc_resolve/src/build_reduced_graph.rs | 68 ++++++++++++------- compiler/rustc_resolve/src/imports.rs | 25 +++++-- compiler/rustc_resolve/src/lib.rs | 4 +- 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 675ea9d1e98ee..2774ed0190f39 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -42,19 +42,19 @@ type Res = def::Res; impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; /// otherwise, reports an error. - pub(crate) fn define_binding( + pub(crate) fn define_binding_local( &mut self, parent: Module<'ra>, ident: Ident, ns: Namespace, binding: NameBinding<'ra>, ) { - if let Err(old_binding) = self.try_define(parent, ident, ns, binding, false) { + if let Err(old_binding) = self.try_define_local(parent, key, binding, false) { self.report_conflict(parent, ident, ns, old_binding, binding); } } - fn define( + fn define_local( &mut self, parent: Module<'ra>, ident: Ident, @@ -65,7 +65,29 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { expn_id: LocalExpnId, ) { let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id); - self.define_binding(parent, ident, ns, binding) + self.define_binding_local(parent, ident, ns, binding) + } + + // Panics when a binding already exists. + fn define_extern( + &self, + parent: Module<'ra>, + ident: Ident, + ns: Namespace, + res: Res, + vis: Visibility>, + span: Span, + expn_id: LocalExpnId, + ) { + let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id); + let key = self.new_disambiguated_key(ident, ns); + self.check_reserved_macro_name(key.ident, binding.res()); + let resolution = &mut *self.resolution(parent, key).borrow_mut(); + if resolution.binding.is_some() { + panic!("An external binding was already defined"); + } + // FIXME: maybe some handling of glob-importers + resolution.binding = Some(binding); } /// Walks up the tree of definitions starting at `def_id`, @@ -188,7 +210,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { visitor.parent_scope.macro_rules } - pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'ra>) { + pub(crate) fn build_reduced_graph_external(&self, module: Module<'ra>) { for child in self.tcx.module_children(module.def_id()) { let parent_scope = ParentScope::module(module, self); self.build_reduced_graph_for_external_crate_res(child, parent_scope) @@ -197,7 +219,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Builds the reduced graph for a single item in an external crate. fn build_reduced_graph_for_external_crate_res( - &mut self, + &self, child: &ModChild, parent_scope: ParentScope<'ra>, ) { @@ -228,7 +250,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { _, ) | Res::PrimTy(..) - | Res::ToolMod => self.define(parent, ident, TypeNS, res, vis, span, expansion), + | Res::ToolMod => self.define_extern(parent, ident, TypeNS, res, vis, span, expansion), Res::Def( DefKind::Fn | DefKind::AssocFn @@ -237,9 +259,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { | DefKind::AssocConst | DefKind::Ctor(..), _, - ) => self.define(parent, ident, ValueNS, res, vis, span, expansion), + ) => self.define_extern(parent, ident, ValueNS, res, vis, span, expansion), Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => { - self.define(parent, ident, MacroNS, res, vis, span, expansion) + self.define_extern(parent, ident, MacroNS, res, vis, span, expansion) } Res::Def( DefKind::TyParam @@ -705,7 +727,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let expansion = parent_scope.expansion; // Define a name in the type namespace if it is not anonymous. - self.r.define(parent, ident, TypeNS, adt_res, adt_vis, adt_span, expansion); + self.r.define_local(parent, ident, TypeNS, adt_res, adt_vis, adt_span, expansion); self.r.feed_visibility(feed, adt_vis); let def_id = feed.key(); @@ -757,7 +779,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } ItemKind::Mod(_, ident, ref mod_kind) => { - self.r.define(parent, ident, TypeNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion); if let ast::ModKind::Loaded(_, _, _, Err(_)) = mod_kind { self.r.mods_with_parse_errors.insert(def_id); @@ -776,10 +798,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { ItemKind::Const(box ConstItem { ident, .. }) | ItemKind::Delegation(box Delegation { ident, .. }) | ItemKind::Static(box StaticItem { ident, .. }) => { - self.r.define(parent, ident, ValueNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, ValueNS, res, vis, sp, expansion); } ItemKind::Fn(box Fn { ident, .. }) => { - self.r.define(parent, ident, ValueNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, ValueNS, res, vis, sp, expansion); // Functions introducing procedural macros reserve a slot // in the macro namespace as well (see #52225). @@ -788,11 +810,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // These items live in the type namespace. ItemKind::TyAlias(box TyAlias { ident, .. }) | ItemKind::TraitAlias(ident, ..) => { - self.r.define(parent, ident, TypeNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion); } ItemKind::Enum(ident, _, _) | ItemKind::Trait(box ast::Trait { ident, .. }) => { - self.r.define(parent, ident, TypeNS, res, vis, sp, expansion); + self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion); self.parent_scope.module = self.r.new_local_module( Some(parent), @@ -844,7 +866,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let feed = self.r.feed(ctor_node_id); let ctor_def_id = feed.key(); let ctor_res = self.res(ctor_def_id); - self.r.define(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion); + self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, sp, expansion); self.r.feed_visibility(feed, ctor_vis); // We need the field visibility spans also for the constructor for E0603. self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata.fields()); @@ -965,7 +987,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { ); } } - self.r.define_binding(parent, ident, TypeNS, imported_binding); + self.r.define_binding_local(parent, ident, TypeNS, imported_binding); } /// Constructs the reduced graph for one foreign item. @@ -982,7 +1004,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let parent = self.parent_scope.module; let expansion = self.parent_scope.expansion; let vis = self.resolve_visibility(&item.vis); - self.r.define(parent, ident, ns, self.res(def_id), vis, item.span, expansion); + self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion); self.r.feed_visibility(feed, vis); } @@ -1241,7 +1263,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { }); self.r.import_use_map.insert(import, Used::Other); let import_binding = self.r.import(binding, import); - self.r.define_binding(self.r.graph_root, ident, MacroNS, import_binding); + self.r.define_binding_local(self.r.graph_root, ident, MacroNS, import_binding); } else { self.r.check_reserved_macro_name(ident, res); self.insert_unused_macro(ident, def_id, item.id); @@ -1269,7 +1291,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if !vis.is_public() { self.insert_unused_macro(ident, def_id, item.id); } - self.r.define(module, ident, MacroNS, res, vis, span, expansion); + self.r.define_local(module, ident, MacroNS, res, vis, span, expansion); self.r.feed_visibility(feed, vis); self.parent_scope.macro_rules } @@ -1405,7 +1427,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if ctxt == AssocCtxt::Trait { let parent = self.parent_scope.module; let expansion = self.parent_scope.expansion; - self.r.define(parent, ident, ns, self.res(def_id), vis, item.span, expansion); + self.r.define_local(parent, ident, ns, self.res(def_id), vis, item.span, expansion); } else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) && ident.name != kw::Underscore { @@ -1493,7 +1515,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let feed = self.r.feed(variant.id); let def_id = feed.key(); let vis = self.resolve_visibility(&variant.vis); - self.r.define(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id); + self.r.define_local(parent, ident, TypeNS, self.res(def_id), vis, variant.span, expn_id); self.r.feed_visibility(feed, vis); // If the variant is marked as non_exhaustive then lower the visibility to within the crate. @@ -1509,7 +1531,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let feed = self.r.feed(ctor_node_id); let ctor_def_id = feed.key(); let ctor_res = self.res(ctor_def_id); - self.r.define(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id); + self.r.define_local(parent, ident, ValueNS, ctor_res, ctor_vis, variant.span, expn_id); self.r.feed_visibility(feed, ctor_vis); } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index b4c15ed1ca7e9..962e128c4c285 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -333,9 +333,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } + // pub(crate) fn try_define( + // &mut self, + // module: Module<'ra>, + // key: BindingKey, + // binding: NameBinding<'ra>, + // warn_ambiguity: bool, + // ) -> Result<(), NameBinding<'ra>> { + // if module.is_local_module() { + // self.try_define_local(module, key, binding, warn_ambiguity) + // } else { + // self.define_extern(module, key, binding); + // Ok(()) + // } + // } + /// Define the name or return the existing binding if there is a collision. /// `update` indicates if the definition is a redefinition of an existing binding. - pub(crate) fn try_define( + pub(crate) fn try_define_local( &mut self, module: Module<'ra>, ident: Ident, @@ -496,7 +511,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; if self.is_accessible_from(binding.vis, scope) { let imported_binding = self.import(binding, *import); - let _ = self.try_define( + let _ = self.try_define_local( import.parent_scope.module, ident, key.ns, @@ -522,7 +537,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let dummy_binding = self.import(dummy_binding, import); self.per_ns(|this, ns| { let module = import.parent_scope.module; - let _ = this.try_define(module, target, ns, dummy_binding, false); + let _ = this.try_define_local(module, target, ns, dummy_binding, false); // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { let key = BindingKey::new(target, ns); @@ -902,7 +917,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // We need the `target`, `source` can be extracted. let imported_binding = this.import(binding, import); - this.define_binding(parent, target, ns, imported_binding); + this.define_binding_local(parent, target, ns, imported_binding); PendingBinding::Ready(Some(imported_binding)) } Err(Determinacy::Determined) => { @@ -1519,7 +1534,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .borrow() .binding() .is_some_and(|binding| binding.warn_ambiguity_recursive()); - let _ = self.try_define( + let _ = self.try_define_local( import.parent_scope.module, key.ident, key.ns, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f38fee8dea5d9..4a85300d1265d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1895,7 +1895,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { import_ids } - fn resolutions(&mut self, module: Module<'ra>) -> &'ra Resolutions<'ra> { + fn resolutions(&self, module: Module<'ra>) -> &'ra Resolutions<'ra> { if module.populate_on_access.get() { module.populate_on_access.set(false); self.build_reduced_graph_external(module); @@ -1904,7 +1904,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn resolution( - &mut self, + &self, module: Module<'ra>, key: BindingKey, ) -> &'ra RefCell> { From 37904a1512ad19794b14707f89a95064279afa82 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Sun, 13 Jul 2025 12:17:09 +0200 Subject: [PATCH 2/8] cleanup old stuff --- compiler/rustc_resolve/src/imports.rs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 962e128c4c285..aec730189bf8d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -333,21 +333,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }) } - // pub(crate) fn try_define( - // &mut self, - // module: Module<'ra>, - // key: BindingKey, - // binding: NameBinding<'ra>, - // warn_ambiguity: bool, - // ) -> Result<(), NameBinding<'ra>> { - // if module.is_local_module() { - // self.try_define_local(module, key, binding, warn_ambiguity) - // } else { - // self.define_extern(module, key, binding); - // Ok(()) - // } - // } - /// Define the name or return the existing binding if there is a collision. /// `update` indicates if the definition is a redefinition of an existing binding. pub(crate) fn try_define_local( From 7ce099ab698445d2dc56b05e126b64cd55c8035f Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Tue, 15 Jul 2025 10:54:03 +0200 Subject: [PATCH 3/8] address review --- compiler/rustc_resolve/src/build_reduced_graph.rs | 12 +++++++----- compiler/rustc_resolve/src/lib.rs | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 2774ed0190f39..88af22b032d8a 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -60,10 +60,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident: Ident, ns: Namespace, res: Res, - vis: Visibility>, + vis: Visibility, span: Span, expn_id: LocalExpnId, ) { + assert!(parent.is_local()); + assert!(res.opt_def_id().is_none_or(|def_id| def_id.is_local())); let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id); self.define_binding_local(parent, ident, ns, binding) } @@ -75,18 +77,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident: Ident, ns: Namespace, res: Res, - vis: Visibility>, + vis: Visibility, span: Span, expn_id: LocalExpnId, ) { - let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id); + assert!(!parent.is_local()); + assert!(!res.opt_def_id().is_some_and(|def_id| def_id.is_local()), "res: {res:?} is local"); + let binding = self.arenas.new_res_binding(res, vis, span, expn_id); let key = self.new_disambiguated_key(ident, ns); - self.check_reserved_macro_name(key.ident, binding.res()); let resolution = &mut *self.resolution(parent, key).borrow_mut(); if resolution.binding.is_some() { panic!("An external binding was already defined"); } - // FIXME: maybe some handling of glob-importers resolution.binding = Some(binding); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 4a85300d1265d..1d5749bcbfbc3 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -702,6 +702,10 @@ impl<'ra> Module<'ra> { } } + fn is_local(self) -> bool { + self.opt_def_id().is_none_or(|def_id| def_id.is_local()) + } + // `self` resolves to the first module ancestor that `is_normal`. fn is_normal(self) -> bool { matches!(self.kind, ModuleKind::Def(DefKind::Mod, _, _)) From 01c162365cb936932d397b35057085ef80457460 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Tue, 15 Jul 2025 15:08:14 +0200 Subject: [PATCH 4/8] check that vis is extern aswell --- compiler/rustc_resolve/src/build_reduced_graph.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 88af22b032d8a..58d1166fdc298 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -83,6 +83,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { assert!(!parent.is_local()); assert!(!res.opt_def_id().is_some_and(|def_id| def_id.is_local()), "res: {res:?} is local"); + let vis = vis.map_id(|def_id| { + assert!(!def_id.is_local()); + def_id + }); let binding = self.arenas.new_res_binding(res, vis, span, expn_id); let key = self.new_disambiguated_key(ident, ns); let resolution = &mut *self.resolution(parent, key).borrow_mut(); From 9e5b09979a68016a20e6416b03a567ce5aece9b8 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Tue, 15 Jul 2025 16:24:50 +0200 Subject: [PATCH 5/8] split `for_each_child` into immutable and mutable versions --- compiler/rustc_expand/src/base.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 4 +-- .../rustc_resolve/src/late/diagnostics.rs | 6 ++-- compiler/rustc_resolve/src/lib.rs | 28 +++++++++++++++---- compiler/rustc_resolve/src/macros.rs | 2 +- 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 1928cfd90482b..ba76ec71aed11 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1144,7 +1144,7 @@ pub trait ResolverExpand { /// Names of specific methods to which glob delegation expands. fn glob_delegation_suffixes( - &mut self, + &self, trait_def_id: DefId, impl_def_id: LocalDefId, ) -> Result)>, Indeterminate>; diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 58d1166fdc298..8b006e575b36b 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1104,7 +1104,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { if let Some(span) = import_all { let import = macro_use_import(self, span, false); self.r.potentially_unused_imports.push(import); - module.for_each_child(self, |this, ident, ns, binding| { + module.for_each_child_mut(self, |this, ident, ns, binding| { if ns == MacroNS { let import = if this.r.is_accessible_from(binding.vis, this.parent_scope.module) { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index f6f45adabe98b..d9ae8f6e06fee 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -523,7 +523,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } pub(crate) fn add_module_candidates( - &mut self, + &self, module: Module<'ra>, names: &mut Vec, filter_fn: &impl Fn(Res) -> bool, @@ -1155,7 +1155,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } fn lookup_import_candidates_from_module( - &mut self, + &self, lookup_ident: Ident, namespace: Namespace, parent_scope: &ParentScope<'ra>, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index ee462d9076491..d85125623ccd1 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2629,7 +2629,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { false } - fn find_module(&mut self, def_id: DefId) -> Option<(Module<'ra>, ImportSuggestion)> { + fn find_module(&self, def_id: DefId) -> Option<(Module<'ra>, ImportSuggestion)> { let mut result = None; let mut seen_modules = FxHashSet::default(); let root_did = self.r.graph_root.def_id(); @@ -2686,7 +2686,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { result } - fn collect_enum_ctors(&mut self, def_id: DefId) -> Option> { + fn collect_enum_ctors(&self, def_id: DefId) -> Option> { self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| { let mut variants = Vec::new(); enum_module.for_each_child(self.r, |_, ident, _, name_binding| { @@ -2703,7 +2703,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { /// Adds a suggestion for using an enum's variant when an enum is used instead. fn suggest_using_enum_variant( - &mut self, + &self, err: &mut Diag<'_>, source: PathSource<'_, '_, '_>, def_id: DefId, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 1d5749bcbfbc3..397a898a8da66 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -652,7 +652,7 @@ impl<'ra> ModuleData<'ra> { } impl<'ra> Module<'ra> { - fn for_each_child<'tcx, R, F>(self, resolver: &mut R, mut f: F) + fn for_each_child_mut<'tcx, R, F>(self, resolver: &mut R, mut f: F) where R: AsMut>, F: FnMut(&mut R, Ident, Namespace, NameBinding<'ra>), @@ -664,10 +664,22 @@ impl<'ra> Module<'ra> { } } + fn for_each_child<'tcx, R, F>(self, resolver: &R, mut f: F) + where + R: AsRef>, + F: FnMut(&R, Ident, Namespace, NameBinding<'ra>), + { + for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() { + if let Some(binding) = name_resolution.borrow().binding { + f(resolver, key.ident, key.ns, binding); + } + } + } + /// This modifies `self` in place. The traits will be stored in `self.traits`. - fn ensure_traits<'tcx, R>(self, resolver: &mut R) + fn ensure_traits<'tcx, R>(self, resolver: &R) where - R: AsMut>, + R: AsRef>, { let mut traits = self.traits.borrow_mut(); if traits.is_none() { @@ -677,7 +689,7 @@ impl<'ra> Module<'ra> { return; } if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() { - collected_traits.push((name, binding, r.as_mut().get_module(def_id))) + collected_traits.push((name, binding, r.as_ref().get_module(def_id))) } }); *traits = Some(collected_traits.into_boxed_slice()); @@ -1341,6 +1353,12 @@ impl<'ra, 'tcx> AsMut> for Resolver<'ra, 'tcx> { } } +impl<'ra, 'tcx> AsRef> for Resolver<'ra, 'tcx> { + fn as_ref(&self) -> &Resolver<'ra, 'tcx> { + self + } +} + impl<'tcx> Resolver<'_, 'tcx> { fn opt_local_def_id(&self, node: NodeId) -> Option { self.opt_feed(node).map(|f| f.key()) @@ -1867,7 +1885,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // We don't reject trait aliases (`trait_module == None`) because we don't have access to their // associated items. fn trait_may_have_item( - &mut self, + &self, trait_module: Option>, assoc_item: Option<(Symbol, Namespace)>, ) -> bool { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 0e8904a7deab6..46ff52f6a9922 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -506,7 +506,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn glob_delegation_suffixes( - &mut self, + &self, trait_def_id: DefId, impl_def_id: LocalDefId, ) -> Result)>, Indeterminate> { From e941e0c5cf9e25436edd4b709ed02f0a63b0962c Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Thu, 17 Jul 2025 20:39:06 +0200 Subject: [PATCH 6/8] some cleanup/rename --- compiler/rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/imports.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 8b006e575b36b..79f7fc7b8bd7e 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -82,7 +82,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { expn_id: LocalExpnId, ) { assert!(!parent.is_local()); - assert!(!res.opt_def_id().is_some_and(|def_id| def_id.is_local()), "res: {res:?} is local"); + assert!(!res.opt_def_id().is_some_and(|def_id| def_id.is_local())); let vis = vis.map_id(|def_id| { assert!(!def_id.is_local()); def_id diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index aec730189bf8d..e05e4b4d7fea8 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -334,7 +334,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } /// Define the name or return the existing binding if there is a collision. - /// `update` indicates if the definition is a redefinition of an existing binding. pub(crate) fn try_define_local( &mut self, module: Module<'ra>, @@ -352,7 +351,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let key = BindingKey::new_disambiguated(ident, ns, || { (module.0.0.lazy_resolutions.borrow().len() + 1).try_into().unwrap() }); - self.update_resolution(module, key, warn_ambiguity, |this, resolution| { + self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| { if let Some(old_binding) = resolution.best_binding() { if res == Res::Err && old_binding.res() != Res::Err { // Do not override real bindings with `Res::Err`s from error recovery. @@ -455,7 +454,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Use `f` to mutate the resolution of the name in the module. // If the resolution becomes a success, define it in the module's glob importers. - fn update_resolution( + fn update_local_resolution( &mut self, module: Module<'ra>, key: BindingKey, @@ -465,6 +464,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { where F: FnOnce(&Resolver<'ra, 'tcx>, &mut NameResolution<'ra>) -> T, { + assert!(module.is_local()); // Ensure that `resolution` isn't borrowed when defining in the module's glob importers, // during which the resolution might end up getting re-defined via a glob cycle. let (binding, t, warn_ambiguity) = { @@ -526,7 +526,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { let key = BindingKey::new(target, ns); - this.update_resolution(module, key, false, |_, resolution| { + this.update_local_resolution(module, key, false, |_, resolution| { resolution.single_imports.swap_remove(&import); }) } @@ -909,7 +909,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Don't remove underscores from `single_imports`, they were never added. if target.name != kw::Underscore { let key = BindingKey::new(target, ns); - this.update_resolution(parent, key, false, |_, resolution| { + this.update_local_resolution(parent, key, false, |_, resolution| { resolution.single_imports.swap_remove(&import); }); } From aa0c3692df4e62c176aed1afd6b0b204c68ea1a9 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Fri, 18 Jul 2025 19:10:16 +0200 Subject: [PATCH 7/8] account for `(non)_glob_binding` change --- .../rustc_resolve/src/build_reduced_graph.rs | 42 ++++++++++++++----- compiler/rustc_resolve/src/lib.rs | 2 +- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 79f7fc7b8bd7e..faeef51558063 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -49,7 +49,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ns: Namespace, binding: NameBinding<'ra>, ) { - if let Err(old_binding) = self.try_define_local(parent, key, binding, false) { + assert!(parent.is_local()); + if let Err(old_binding) = self.try_define_local(parent, ident, ns, binding, false) { self.report_conflict(parent, ident, ns, old_binding, binding); } } @@ -60,17 +61,43 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident: Ident, ns: Namespace, res: Res, - vis: Visibility, + vis: Visibility, // Implictly local span: Span, expn_id: LocalExpnId, ) { assert!(parent.is_local()); assert!(res.opt_def_id().is_none_or(|def_id| def_id.is_local())); let binding = self.arenas.new_res_binding(res, vis.to_def_id(), span, expn_id); - self.define_binding_local(parent, ident, ns, binding) + self.define_binding_local(parent, ident, ns, binding); + } + + /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; + /// otherwise, panic. + pub(crate) fn define_binding_extern( + &self, + parent: Module<'ra>, + ident: Ident, + ns: Namespace, + binding: NameBinding<'ra>, + ) { + assert!(!parent.is_local()); + // Even if underscore names cannot be looked up, we still need to add them to modules, + // because they can be fetched by glob imports from those modules, and bring traits + // into scope both directly and through glob imports. + let key = BindingKey::new_disambiguated(ident, ns, || { + (parent.0.0.lazy_resolutions.borrow().len() + 1).try_into().unwrap() + }); + let resolution = &mut *self.resolution(parent, key).borrow_mut(); + let resolution_binding = if binding.is_glob_import() { + &mut resolution.glob_binding + } else { + &mut resolution.non_glob_binding + }; + if resolution_binding.replace(binding).is_some() { + panic!("An external binding was already defined"); + } } - // Panics when a binding already exists. fn define_extern( &self, parent: Module<'ra>, @@ -88,12 +115,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { def_id }); let binding = self.arenas.new_res_binding(res, vis, span, expn_id); - let key = self.new_disambiguated_key(ident, ns); - let resolution = &mut *self.resolution(parent, key).borrow_mut(); - if resolution.binding.is_some() { - panic!("An external binding was already defined"); - } - resolution.binding = Some(binding); + self.define_binding_extern(parent, ident, ns, binding); } /// Walks up the tree of definitions starting at `def_id`, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 397a898a8da66..8cd48ded68ea2 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -670,7 +670,7 @@ impl<'ra> Module<'ra> { F: FnMut(&R, Ident, Namespace, NameBinding<'ra>), { for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() { - if let Some(binding) = name_resolution.borrow().binding { + if let Some(binding) = name_resolution.borrow().best_binding() { f(resolver, key.ident, key.ns, binding); } } From 110a3d96639ce2f9613f320b46f04b94478dce0c Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Sat, 19 Jul 2025 03:51:17 +0200 Subject: [PATCH 8/8] spell check --- compiler/rustc_resolve/src/build_reduced_graph.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index faeef51558063..823b51986fdce 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -61,7 +61,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident: Ident, ns: Namespace, res: Res, - vis: Visibility, // Implictly local + vis: Visibility, // Implicitly local span: Span, expn_id: LocalExpnId, ) {