Skip to content

Commit b5df05d

Browse files
authored
Unrolled build for #144013
Rollup merge of #144013 - petrochenkov:disambunder, r=oli-obk resolve: Make disambiguators for underscore bindings module-local Disambiguators attached to underscore name bindings (like `const _: u8 = something;`) do not need to be globally unique, they just need to be unique inside the module in which they live, because the bindings in a module are basically kept as `Map<BindingKey, SomeData>`. Also, the specific values of the disambiguators are not important, so a glob import of `const _` may have a different disambiguator than the original `const _` itself. So in this PR the disambiguator is just set to the current number of bindings in the module. This removes one more piece of global mutable state from resolver and unblocks #143884.
2 parents 6caa224 + 998df3a commit b5df05d

File tree

4 files changed

+58
-45
lines changed

4 files changed

+58
-45
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
4949
ns: Namespace,
5050
binding: NameBinding<'ra>,
5151
) {
52-
let key = self.new_disambiguated_key(ident, ns);
53-
if let Err(old_binding) = self.try_define(parent, key, binding, false) {
52+
if let Err(old_binding) = self.try_define(parent, ident, ns, binding, false) {
5453
self.report_conflict(parent, ident, ns, old_binding, binding);
5554
}
5655
}
@@ -442,16 +441,18 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
442441

443442
self.r.indeterminate_imports.push(import);
444443
match import.kind {
445-
// Don't add unresolved underscore imports to modules
446-
ImportKind::Single { target: Ident { name: kw::Underscore, .. }, .. } => {}
447444
ImportKind::Single { target, type_ns_only, .. } => {
448-
self.r.per_ns(|this, ns| {
449-
if !type_ns_only || ns == TypeNS {
450-
let key = BindingKey::new(target, ns);
451-
let mut resolution = this.resolution(current_module, key).borrow_mut();
452-
resolution.single_imports.insert(import);
453-
}
454-
});
445+
// Don't add underscore imports to `single_imports`
446+
// because they cannot define any usable names.
447+
if target.name != kw::Underscore {
448+
self.r.per_ns(|this, ns| {
449+
if !type_ns_only || ns == TypeNS {
450+
let key = BindingKey::new(target, ns);
451+
let mut resolution = this.resolution(current_module, key).borrow_mut();
452+
resolution.single_imports.insert(import);
453+
}
454+
});
455+
}
455456
}
456457
// We don't add prelude imports to the globs since they only affect lexical scopes,
457458
// which are not relevant to import resolution.
@@ -1405,9 +1406,12 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
14051406
let parent = self.parent_scope.module;
14061407
let expansion = self.parent_scope.expansion;
14071408
self.r.define(parent, ident, ns, self.res(def_id), vis, item.span, expansion);
1408-
} else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob) {
1409+
} else if !matches!(&item.kind, AssocItemKind::Delegation(deleg) if deleg.from_glob)
1410+
&& ident.name != kw::Underscore
1411+
{
1412+
// Don't add underscore names, they cannot be looked up anyway.
14091413
let impl_def_id = self.r.tcx.local_parent(local_def_id);
1410-
let key = BindingKey::new(ident.normalize_to_macros_2_0(), ns);
1414+
let key = BindingKey::new(ident, ns);
14111415
self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key);
14121416
}
14131417

compiler/rustc_resolve/src/imports.rs

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

28-
use crate::Namespace::*;
28+
use crate::Namespace::{self, *};
2929
use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
3030
use crate::errors::{
3131
CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
@@ -338,13 +338,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
338338
pub(crate) fn try_define(
339339
&mut self,
340340
module: Module<'ra>,
341-
key: BindingKey,
341+
ident: Ident,
342+
ns: Namespace,
342343
binding: NameBinding<'ra>,
343344
warn_ambiguity: bool,
344345
) -> Result<(), NameBinding<'ra>> {
345346
let res = binding.res();
346-
self.check_reserved_macro_name(key.ident, res);
347+
self.check_reserved_macro_name(ident, res);
347348
self.set_binding_parent_module(binding, module);
349+
// Even if underscore names cannot be looked up, we still need to add them to modules,
350+
// because they can be fetched by glob imports from those modules, and bring traits
351+
// into scope both directly and through glob imports.
352+
let key = BindingKey::new_disambiguated(ident, ns, || {
353+
(module.0.0.lazy_resolutions.borrow().len() + 1).try_into().unwrap()
354+
});
348355
self.update_resolution(module, key, warn_ambiguity, |this, resolution| {
349356
if let Some(old_binding) = resolution.best_binding() {
350357
if res == Res::Err && old_binding.res() != Res::Err {
@@ -383,7 +390,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
383390
(old_glob @ true, false) | (old_glob @ false, true) => {
384391
let (glob_binding, non_glob_binding) =
385392
if old_glob { (old_binding, binding) } else { (binding, old_binding) };
386-
if key.ns == MacroNS
393+
if ns == MacroNS
387394
&& non_glob_binding.expansion != LocalExpnId::ROOT
388395
&& glob_binding.res() != non_glob_binding.res()
389396
{
@@ -489,10 +496,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
489496
};
490497
if self.is_accessible_from(binding.vis, scope) {
491498
let imported_binding = self.import(binding, *import);
492-
let key = BindingKey { ident, ..key };
493499
let _ = self.try_define(
494500
import.parent_scope.module,
495-
key,
501+
ident,
502+
key.ns,
496503
imported_binding,
497504
warn_ambiguity,
498505
);
@@ -514,11 +521,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
514521
let dummy_binding = self.dummy_binding;
515522
let dummy_binding = self.import(dummy_binding, import);
516523
self.per_ns(|this, ns| {
517-
let key = BindingKey::new(target, ns);
518-
let _ = this.try_define(import.parent_scope.module, key, dummy_binding, false);
519-
this.update_resolution(import.parent_scope.module, key, false, |_, resolution| {
520-
resolution.single_imports.swap_remove(&import);
521-
})
524+
let module = import.parent_scope.module;
525+
let _ = this.try_define(module, target, ns, dummy_binding, false);
526+
// Don't remove underscores from `single_imports`, they were never added.
527+
if target.name != kw::Underscore {
528+
let key = BindingKey::new(target, ns);
529+
this.update_resolution(module, key, false, |_, resolution| {
530+
resolution.single_imports.swap_remove(&import);
531+
})
532+
}
522533
});
523534
self.record_use(target, dummy_binding, Used::Other);
524535
} else if import.imported_module.get().is_none() {
@@ -895,7 +906,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
895906
PendingBinding::Ready(Some(imported_binding))
896907
}
897908
Err(Determinacy::Determined) => {
898-
// Don't update the resolution for underscores, because it was never added.
909+
// Don't remove underscores from `single_imports`, they were never added.
899910
if target.name != kw::Underscore {
900911
let key = BindingKey::new(target, ns);
901912
this.update_resolution(parent, key, false, |_, resolution| {
@@ -1510,7 +1521,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15101521
.is_some_and(|binding| binding.warn_ambiguity_recursive());
15111522
let _ = self.try_define(
15121523
import.parent_scope.module,
1513-
key,
1524+
key.ident,
1525+
key.ns,
15141526
imported_binding,
15151527
warn_ambiguity,
15161528
);

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-underscore 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

@@ -1087,8 +1098,6 @@ pub struct Resolver<'ra, 'tcx> {
10871098
extern_module_map: RefCell<FxIndexMap<DefId, Module<'ra>>>,
10881099
binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,
10891100

1090-
underscore_disambiguator: u32,
1091-
10921101
/// Maps glob imports to the names of items actually imported.
10931102
glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
10941103
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
local_module_map,
15071515
extern_module_map: Default::default(),
@@ -1887,17 +1895,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18871895
import_ids
18881896
}
18891897

1890-
fn new_disambiguated_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
1891-
let ident = ident.normalize_to_macros_2_0();
1892-
let disambiguator = if ident.name == kw::Underscore {
1893-
self.underscore_disambiguator += 1;
1894-
self.underscore_disambiguator
1895-
} else {
1896-
0
1897-
};
1898-
BindingKey { ident, ns, disambiguator }
1899-
}
1900-
19011898
fn resolutions(&mut self, module: Module<'ra>) -> &'ra Resolutions<'ra> {
19021899
if module.populate_on_access.get() {
19031900
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
@@ -530,7 +530,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
530530
target_trait.for_each_child(self, |this, ident, ns, _binding| {
531531
// FIXME: Adjust hygiene for idents from globs, like for glob imports.
532532
if let Some(overriding_keys) = this.impl_binding_keys.get(&impl_def_id)
533-
&& overriding_keys.contains(&BindingKey::new(ident.normalize_to_macros_2_0(), ns))
533+
&& overriding_keys.contains(&BindingKey::new(ident, ns))
534534
{
535535
// The name is overridden, do not produce it from the glob delegation.
536536
} else {

0 commit comments

Comments
 (0)