Skip to content

Commit 1a2597b

Browse files
committed
Don't use gensym_if_underscore to resolve _ bindings
Instead add a disambiguator to the keys used for distinguishing resolutions.
1 parent a975259 commit 1a2597b

File tree

4 files changed

+91
-63
lines changed

4 files changed

+91
-63
lines changed

src/librustc_resolve/build_reduced_graph.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ impl<'a> Resolver<'a> {
9393
where T: ToNameBinding<'a>,
9494
{
9595
let binding = def.to_name_binding(self.arenas);
96-
if let Err(old_binding) = self.try_define(parent, ident, ns, binding) {
96+
let key = self.new_key(ident, ns);
97+
if let Err(old_binding) = self.try_define(parent, key, binding) {
9798
self.report_conflict(parent, ident, ns, old_binding, &binding);
9899
}
99100
}
@@ -349,9 +350,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
349350

350351
self.r.indeterminate_imports.push(directive);
351352
match directive.subclass {
353+
// Don't add unresolved underscore imports to modules
354+
SingleImport { target: Ident { name: kw::Underscore, .. }, .. } => {}
352355
SingleImport { target, type_ns_only, .. } => {
353356
self.r.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
354-
let mut resolution = this.resolution(current_module, target, ns).borrow_mut();
357+
let key = this.new_key(target, ns);
358+
let mut resolution = this.resolution(current_module, key).borrow_mut();
355359
resolution.add_single_import(directive);
356360
});
357361
}
@@ -407,7 +411,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
407411
};
408412
match use_tree.kind {
409413
ast::UseTreeKind::Simple(rename, ..) => {
410-
let mut ident = use_tree.ident().gensym_if_underscore();
414+
let mut ident = use_tree.ident();
411415
let mut module_path = prefix;
412416
let mut source = module_path.pop().unwrap();
413417
let mut type_ns_only = false;
@@ -585,7 +589,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
585589
let parent_scope = &self.parent_scope;
586590
let parent = parent_scope.module;
587591
let expansion = parent_scope.expansion;
588-
let ident = item.ident.gensym_if_underscore();
592+
let ident = item.ident;
589593
let sp = item.span;
590594
let vis = self.resolve_visibility(&item.vis);
591595

@@ -850,10 +854,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
850854
fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<NodeId>) {
851855
let parent = self.parent_scope.module;
852856
let Export { ident, res, vis, span } = child;
853-
// FIXME: We shouldn't create the gensym here, it should come from metadata,
854-
// but metadata cannot encode gensyms currently, so we create it here.
855-
// This is only a guess, two equivalent idents may incorrectly get different gensyms here.
856-
let ident = ident.gensym_if_underscore();
857857
let expansion = ExpnId::root(); // FIXME(jseyfried) intercrate hygiene
858858
// Record primary definitions.
859859
match res {

src/librustc_resolve/diagnostics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ impl<'a> Resolver<'a> {
8080
names: &mut Vec<TypoSuggestion>,
8181
filter_fn: &impl Fn(Res) -> bool,
8282
) {
83-
for (&(ident, _), resolution) in self.resolutions(module).borrow().iter() {
83+
for (key, resolution) in self.resolutions(module).borrow().iter() {
8484
if let Some(binding) = resolution.borrow().binding {
8585
let res = binding.res();
8686
if filter_fn(res) {
87-
names.push(TypoSuggestion::from_res(ident.name, res));
87+
names.push(TypoSuggestion::from_res(key.ident.name, res));
8888
}
8989
}
9090
}
@@ -849,7 +849,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
849849
}
850850

851851
let resolutions = self.r.resolutions(crate_module).borrow();
852-
let resolution = resolutions.get(&(ident, MacroNS))?;
852+
let resolution = resolutions.get(&self.r.new_key(ident, MacroNS))?;
853853
let binding = resolution.borrow().binding()?;
854854
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
855855
let module_name = crate_module.kind.name().unwrap();

src/librustc_resolve/lib.rs

+33-5
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,22 @@ impl ModuleKind {
431431
}
432432
}
433433

434-
type Resolutions<'a> = RefCell<FxIndexMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>;
434+
/// A key that identifies a binding in a given `Module`.
435+
///
436+
/// Multiple bindings in the same module can have the same key (in a valid
437+
/// program) if all but one of them come from glob imports.
438+
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
439+
struct BindingKey {
440+
/// The identifier for the binding, aways the `modern` version of the
441+
/// identifier.
442+
ident: Ident,
443+
ns: Namespace,
444+
/// 0 if ident is not `_`, otherwise a value that's unique to the specific
445+
/// `_` in the expanded AST that introduced this binding.
446+
disambiguator: u32,
447+
}
448+
449+
type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution<'a>>>>;
435450

436451
/// One node in the tree of modules.
437452
pub struct ModuleData<'a> {
@@ -491,8 +506,8 @@ impl<'a> ModuleData<'a> {
491506
fn for_each_child<R, F>(&'a self, resolver: &mut R, mut f: F)
492507
where R: AsMut<Resolver<'a>>, F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>)
493508
{
494-
for (&(ident, ns), name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
495-
name_resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding));
509+
for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
510+
name_resolution.borrow().binding.map(|binding| f(resolver, key.ident, key.ns, binding));
496511
}
497512
}
498513

@@ -879,6 +894,7 @@ pub struct Resolver<'a> {
879894
module_map: FxHashMap<DefId, Module<'a>>,
880895
extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>,
881896
binding_parent_modules: FxHashMap<PtrKey<'a, NameBinding<'a>>, Module<'a>>,
897+
underscore_disambiguator: u32,
882898

883899
/// Maps glob imports to the names of items actually imported.
884900
pub glob_map: GlobMap,
@@ -1156,6 +1172,7 @@ impl<'a> Resolver<'a> {
11561172
label_res_map: Default::default(),
11571173
export_map: FxHashMap::default(),
11581174
trait_map: Default::default(),
1175+
underscore_disambiguator: 0,
11591176
empty_module,
11601177
module_map,
11611178
block_map: Default::default(),
@@ -1280,6 +1297,17 @@ impl<'a> Resolver<'a> {
12801297
self.arenas.alloc_module(module)
12811298
}
12821299

1300+
fn new_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
1301+
let ident = ident.modern();
1302+
let disambiguator = if ident.name == kw::Underscore {
1303+
self.underscore_disambiguator += 1;
1304+
self.underscore_disambiguator
1305+
} else {
1306+
0
1307+
};
1308+
BindingKey { ident, ns, disambiguator }
1309+
}
1310+
12831311
fn resolutions(&mut self, module: Module<'a>) -> &'a Resolutions<'a> {
12841312
if module.populate_on_access.get() {
12851313
module.populate_on_access.set(false);
@@ -1288,9 +1316,9 @@ impl<'a> Resolver<'a> {
12881316
&module.lazy_resolutions
12891317
}
12901318

1291-
fn resolution(&mut self, module: Module<'a>, ident: Ident, ns: Namespace)
1319+
fn resolution(&mut self, module: Module<'a>, key: BindingKey)
12921320
-> &'a RefCell<NameResolution<'a>> {
1293-
*self.resolutions(module).borrow_mut().entry((ident.modern(), ns))
1321+
*self.resolutions(module).borrow_mut().entry(key)
12941322
.or_insert_with(|| self.arenas.alloc_name_resolution())
12951323
}
12961324

0 commit comments

Comments
 (0)