Skip to content

Commit 6a70a41

Browse files
committed
resolve: Make disambiguators for underscore bindings module-local
1 parent 231257f commit 6a70a41

File tree

4 files changed

+53
-44
lines changed

4 files changed

+53
-44
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
7575
T: ToNameBinding<'ra>,
7676
{
7777
let binding = def.to_name_binding(self.arenas);
78-
let key = self.new_disambiguated_key(ident, ns);
79-
if let Err(old_binding) = self.try_define(parent, key, binding, false) {
78+
if let Err(old_binding) = self.try_define(parent, ident, ns, binding, false) {
8079
self.report_conflict(parent, ident, ns, old_binding, binding);
8180
}
8281
}
@@ -452,16 +451,18 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
452451

453452
self.r.indeterminate_imports.push(import);
454453
match import.kind {
455-
// Don't add unresolved underscore imports to modules
456-
ImportKind::Single { target: Ident { name: kw::Underscore, .. }, .. } => {}
457454
ImportKind::Single { target, type_ns_only, .. } => {
458-
self.r.per_ns(|this, ns| {
459-
if !type_ns_only || ns == TypeNS {
460-
let key = BindingKey::new(target, ns);
461-
let mut resolution = this.resolution(current_module, key).borrow_mut();
462-
resolution.single_imports.insert(import);
463-
}
464-
});
455+
// Don't add underscore imports to `single_imports`
456+
// because they cannot define any usable names.
457+
if target.name != kw::Underscore {
458+
self.r.per_ns(|this, ns| {
459+
if !type_ns_only || ns == TypeNS {
460+
let key = BindingKey::new(target, ns);
461+
let mut resolution = this.resolution(current_module, key).borrow_mut();
462+
resolution.single_imports.insert(import);
463+
}
464+
});
465+
}
465466
}
466467
// We don't add prelude imports to the globs since they only affect lexical scopes,
467468
// which are not relevant to import resolution.
@@ -1421,7 +1422,9 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
14211422
self.r.define(parent, ident, ns, (self.res(def_id), vis, item.span, expansion));
14221423
} else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) {
14231424
let impl_def_id = self.r.tcx.local_parent(local_def_id);
1424-
let key = BindingKey::new(ident.normalize_to_macros_2_0(), ns);
1425+
let key = BindingKey::new_disambiguated(ident, ns, || {
1426+
(self.r.impl_binding_keys.len() + 1).try_into().unwrap()
1427+
});
14251428
self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key);
14261429
}
14271430

compiler/rustc_resolve/src/imports.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_span::{Ident, Span, Symbol, kw, sym};
2424
use smallvec::SmallVec;
2525
use tracing::debug;
2626

27-
use crate::Namespace::*;
27+
use crate::Namespace::{self, *};
2828
use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
2929
use crate::errors::{
3030
CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
@@ -337,13 +337,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
337337
pub(crate) fn try_define(
338338
&mut self,
339339
module: Module<'ra>,
340-
key: BindingKey,
340+
ident: Ident,
341+
ns: Namespace,
341342
binding: NameBinding<'ra>,
342343
warn_ambiguity: bool,
343344
) -> Result<(), NameBinding<'ra>> {
344345
let res = binding.res();
345-
self.check_reserved_macro_name(key.ident, res);
346+
self.check_reserved_macro_name(ident, res);
346347
self.set_binding_parent_module(binding, module);
348+
let key = BindingKey::new_disambiguated(ident, ns, || {
349+
(module.0.0.lazy_resolutions.borrow().len() + 1).try_into().unwrap()
350+
});
347351
self.update_resolution(module, key, warn_ambiguity, |this, resolution| {
348352
if let Some(old_binding) = resolution.best_binding() {
349353
if res == Res::Err && old_binding.res() != Res::Err {
@@ -382,7 +386,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
382386
(old_glob @ true, false) | (old_glob @ false, true) => {
383387
let (glob_binding, non_glob_binding) =
384388
if old_glob { (old_binding, binding) } else { (binding, old_binding) };
385-
if key.ns == MacroNS
389+
if ns == MacroNS
386390
&& non_glob_binding.expansion != LocalExpnId::ROOT
387391
&& glob_binding.res() != non_glob_binding.res()
388392
{
@@ -488,10 +492,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
488492
};
489493
if self.is_accessible_from(binding.vis, scope) {
490494
let imported_binding = self.import(binding, *import);
491-
let key = BindingKey { ident, ..key };
492495
let _ = self.try_define(
493496
import.parent_scope.module,
494-
key,
497+
ident,
498+
key.ns,
495499
imported_binding,
496500
warn_ambiguity,
497501
);
@@ -513,11 +517,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
513517
let dummy_binding = self.dummy_binding;
514518
let dummy_binding = self.import(dummy_binding, import);
515519
self.per_ns(|this, ns| {
516-
let key = BindingKey::new(target, ns);
517-
let _ = this.try_define(import.parent_scope.module, key, dummy_binding, false);
518-
this.update_resolution(import.parent_scope.module, key, false, |_, resolution| {
519-
resolution.single_imports.swap_remove(&import);
520-
})
520+
let module = import.parent_scope.module;
521+
let _ = this.try_define(module, target, ns, dummy_binding, false);
522+
// Don't remove underscores from `single_imports`, they were never added.
523+
if target.name != kw::Underscore {
524+
let key = BindingKey::new(target, ns);
525+
this.update_resolution(module, key, false, |_, resolution| {
526+
resolution.single_imports.swap_remove(&import);
527+
})
528+
}
521529
});
522530
self.record_use(target, dummy_binding, Used::Other);
523531
} else if import.imported_module.get().is_none() {
@@ -879,7 +887,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
879887
PendingBinding::Ready(Some(imported_binding))
880888
}
881889
Err(Determinacy::Determined) => {
882-
// Don't update the resolution for underscores, because it was never added.
890+
// Don't remove underscores from `single_imports`, they were never added.
883891
if target.name != kw::Underscore {
884892
let key = BindingKey::new(target, ns);
885893
this.update_resolution(parent, key, false, |_, resolution| {
@@ -1494,7 +1502,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14941502
.is_some_and(|binding| binding.warn_ambiguity_recursive());
14951503
let _ = self.try_define(
14961504
import.parent_scope.module,
1497-
key,
1505+
key.ident,
1506+
key.ns,
14981507
imported_binding,
14991508
warn_ambiguity,
15001509
);

compiler/rustc_resolve/src/lib.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -532,15 +532,26 @@ struct BindingKey {
532532
/// identifier.
533533
ident: Ident,
534534
ns: Namespace,
535-
/// 0 if ident is not `_`, otherwise a value that's unique to the specific
536-
/// `_` in the expanded AST that introduced this binding.
535+
/// When we add an underscore binding (with ident `_`) to some module, this field has
536+
/// a non-zero value that uniquely identifies this binding in that module.
537+
/// For non-undersore bindings this field is zero.
538+
/// When a key is constructed for name lookup (as opposed to name definition), this field is
539+
/// also zero, even for underscore names, so for underscores the lookup will never succeed.
537540
disambiguator: u32,
538541
}
539542

540543
impl BindingKey {
541544
fn new(ident: Ident, ns: Namespace) -> Self {
542-
let ident = ident.normalize_to_macros_2_0();
543-
BindingKey { ident, ns, disambiguator: 0 }
545+
BindingKey { ident: ident.normalize_to_macros_2_0(), ns, disambiguator: 0 }
546+
}
547+
548+
fn new_disambiguated(
549+
ident: Ident,
550+
ns: Namespace,
551+
disambiguator: impl FnOnce() -> u32,
552+
) -> BindingKey {
553+
let disambiguator = if ident.name == kw::Underscore { disambiguator() } else { 0 };
554+
BindingKey { ident: ident.normalize_to_macros_2_0(), ns, disambiguator }
544555
}
545556
}
546557

@@ -1103,8 +1114,6 @@ pub struct Resolver<'ra, 'tcx> {
11031114
module_map: FxIndexMap<DefId, Module<'ra>>,
11041115
binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,
11051116

1106-
underscore_disambiguator: u32,
1107-
11081117
/// Maps glob imports to the names of items actually imported.
11091118
glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
11101119
glob_error: Option<ErrorGuaranteed>,
@@ -1501,7 +1510,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15011510
extern_crate_map: Default::default(),
15021511
module_children: Default::default(),
15031512
trait_map: NodeMap::default(),
1504-
underscore_disambiguator: 0,
15051513
empty_module,
15061514
module_map,
15071515
block_map: Default::default(),
@@ -1884,17 +1892,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18841892
import_ids
18851893
}
18861894

1887-
fn new_disambiguated_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
1888-
let ident = ident.normalize_to_macros_2_0();
1889-
let disambiguator = if ident.name == kw::Underscore {
1890-
self.underscore_disambiguator += 1;
1891-
self.underscore_disambiguator
1892-
} else {
1893-
0
1894-
};
1895-
BindingKey { ident, ns, disambiguator }
1896-
}
1897-
18981895
fn resolutions(&mut self, module: Module<'ra>) -> &'ra Resolutions<'ra> {
18991896
if module.populate_on_access.get() {
19001897
module.populate_on_access.set(false);

compiler/rustc_resolve/src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
531531
target_trait.for_each_child(self, |this, ident, ns, _binding| {
532532
// FIXME: Adjust hygiene for idents from globs, like for glob imports.
533533
if let Some(overriding_keys) = this.impl_binding_keys.get(&impl_def_id)
534-
&& overriding_keys.contains(&BindingKey::new(ident.normalize_to_macros_2_0(), ns))
534+
&& overriding_keys.contains(&BindingKey::new(ident, ns))
535535
{
536536
// The name is overridden, do not produce it from the glob delegation.
537537
} else {

0 commit comments

Comments
 (0)