Skip to content

Commit 4ce8038

Browse files
committed
Auto merge of #31648 - jseyfried:fix_diagnostics, r=nrc
This PR fixes two unrelated diagnostics bugs in resolve. First, it reports privacy errors for an import only after the import resolution is determined, fixing #31402. Second, it expands the per-module map from block ids to anonymous modules so that it also maps module declarations ids to modules, and it uses this map to in `with_scope` to fix #31644. r? @nrc
2 parents 69ad912 + 81d5d02 commit 4ce8038

File tree

4 files changed

+43
-92
lines changed

4 files changed

+43
-92
lines changed

src/librustc_resolve/build_reduced_graph.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
306306
let def = Def::Mod(self.ast_map.local_def_id(item.id));
307307
let module = self.new_module(parent_link, Some(def), false, is_public);
308308
self.define(parent, name, TypeNS, (module, sp));
309+
parent.module_children.borrow_mut().insert(item.id, module);
309310
module
310311
}
311312

@@ -474,7 +475,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
474475

475476
let parent_link = BlockParentLink(parent, block_id);
476477
let new_module = self.new_module(parent_link, None, false, false);
477-
parent.anonymous_children.borrow_mut().insert(block_id, new_module);
478+
parent.module_children.borrow_mut().insert(block_id, new_module);
478479
new_module
479480
} else {
480481
parent

src/librustc_resolve/lib.rs

+18-57
Original file line numberDiff line numberDiff line change
@@ -798,12 +798,12 @@ pub struct ModuleS<'a> {
798798
is_public: bool,
799799
is_extern_crate: bool,
800800

801-
children: RefCell<HashMap<(Name, Namespace), NameResolution<'a>>>,
801+
resolutions: RefCell<HashMap<(Name, Namespace), NameResolution<'a>>>,
802802
imports: RefCell<Vec<ImportDirective>>,
803803

804-
// The anonymous children of this node. Anonymous children are pseudo-
805-
// modules that are implicitly created around items contained within
806-
// blocks.
804+
// The module children of this node, including normal modules and anonymous modules.
805+
// Anonymous children are pseudo-modules that are implicitly created around items
806+
// contained within blocks.
807807
//
808808
// For example, if we have this:
809809
//
@@ -815,7 +815,7 @@ pub struct ModuleS<'a> {
815815
//
816816
// There will be an anonymous module created around `g` with the ID of the
817817
// entry block for `f`.
818-
anonymous_children: RefCell<NodeMap<Module<'a>>>,
818+
module_children: RefCell<NodeMap<Module<'a>>>,
819819

820820
shadowed_traits: RefCell<Vec<&'a NameBinding<'a>>>,
821821

@@ -846,9 +846,9 @@ impl<'a> ModuleS<'a> {
846846
def: def,
847847
is_public: is_public,
848848
is_extern_crate: false,
849-
children: RefCell::new(HashMap::new()),
849+
resolutions: RefCell::new(HashMap::new()),
850850
imports: RefCell::new(Vec::new()),
851-
anonymous_children: RefCell::new(NodeMap()),
851+
module_children: RefCell::new(NodeMap()),
852852
shadowed_traits: RefCell::new(Vec::new()),
853853
glob_count: Cell::new(0),
854854
pub_count: Cell::new(0),
@@ -863,7 +863,7 @@ impl<'a> ModuleS<'a> {
863863
let glob_count =
864864
if allow_private_imports { self.glob_count.get() } else { self.pub_glob_count.get() };
865865

866-
self.children.borrow().get(&(name, ns)).cloned().unwrap_or_default().result(glob_count)
866+
self.resolutions.borrow().get(&(name, ns)).cloned().unwrap_or_default().result(glob_count)
867867
.and_then(|binding| {
868868
let allowed = allow_private_imports || !binding.is_import() || binding.is_public();
869869
if allowed { Success(binding) } else { Failed(None) }
@@ -873,7 +873,7 @@ impl<'a> ModuleS<'a> {
873873
// Define the name or return the existing binding if there is a collision.
874874
fn try_define_child(&self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>)
875875
-> Result<(), &'a NameBinding<'a>> {
876-
let mut children = self.children.borrow_mut();
876+
let mut children = self.resolutions.borrow_mut();
877877
let resolution = children.entry((name, ns)).or_insert_with(Default::default);
878878

879879
// FIXME #31379: We can use methods from imported traits shadowed by non-import items
@@ -889,31 +889,23 @@ impl<'a> ModuleS<'a> {
889889
}
890890

891891
fn increment_outstanding_references_for(&self, name: Name, ns: Namespace) {
892-
let mut children = self.children.borrow_mut();
892+
let mut children = self.resolutions.borrow_mut();
893893
children.entry((name, ns)).or_insert_with(Default::default).outstanding_references += 1;
894894
}
895895

896896
fn decrement_outstanding_references_for(&self, name: Name, ns: Namespace) {
897-
match self.children.borrow_mut().get_mut(&(name, ns)).unwrap().outstanding_references {
897+
match self.resolutions.borrow_mut().get_mut(&(name, ns)).unwrap().outstanding_references {
898898
0 => panic!("No more outstanding references!"),
899899
ref mut outstanding_references => { *outstanding_references -= 1; }
900900
}
901901
}
902902

903903
fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
904-
for (&(name, ns), name_resolution) in self.children.borrow().iter() {
904+
for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
905905
name_resolution.binding.map(|binding| f(name, ns, binding));
906906
}
907907
}
908908

909-
fn for_each_local_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
910-
self.for_each_child(|name, ns, name_binding| {
911-
if !name_binding.is_import() && !name_binding.is_extern_crate() {
912-
f(name, ns, name_binding)
913-
}
914-
})
915-
}
916-
917909
fn def_id(&self) -> Option<DefId> {
918910
self.def.as_ref().map(Def::def_id)
919911
}
@@ -1640,20 +1632,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
16401632
}
16411633

16421634
// Descend into children and anonymous children.
1643-
build_reduced_graph::populate_module_if_necessary(self, module_);
1644-
1645-
module_.for_each_local_child(|_, _, child_node| {
1646-
match child_node.module() {
1647-
None => {
1648-
// Continue.
1649-
}
1650-
Some(child_module) => {
1651-
self.report_unresolved_imports(child_module);
1652-
}
1653-
}
1654-
});
1655-
1656-
for (_, module_) in module_.anonymous_children.borrow().iter() {
1635+
for (_, module_) in module_.module_children.borrow().iter() {
16571636
self.report_unresolved_imports(module_);
16581637
}
16591638
}
@@ -1676,32 +1655,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
16761655
// generate a fake "implementation scope" containing all the
16771656
// implementations thus found, for compatibility with old resolve pass.
16781657

1679-
fn with_scope<F>(&mut self, name: Option<Name>, f: F)
1658+
fn with_scope<F>(&mut self, id: NodeId, f: F)
16801659
where F: FnOnce(&mut Resolver)
16811660
{
16821661
let orig_module = self.current_module;
16831662

16841663
// Move down in the graph.
1685-
match name {
1686-
None => {
1687-
// Nothing to do.
1688-
}
1689-
Some(name) => {
1690-
build_reduced_graph::populate_module_if_necessary(self, &orig_module);
1691-
1692-
if let Success(name_binding) = orig_module.resolve_name(name, TypeNS, false) {
1693-
match name_binding.module() {
1694-
None => {
1695-
debug!("!!! (with scope) didn't find module for `{}` in `{}`",
1696-
name,
1697-
module_to_string(orig_module));
1698-
}
1699-
Some(module) => {
1700-
self.current_module = module;
1701-
}
1702-
}
1703-
}
1704-
}
1664+
if let Some(module) = orig_module.module_children.borrow().get(&id) {
1665+
self.current_module = module;
17051666
}
17061667

17071668
f(self);
@@ -1825,7 +1786,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
18251786
}
18261787

18271788
ItemMod(_) | ItemForeignMod(_) => {
1828-
self.with_scope(Some(name), |this| {
1789+
self.with_scope(item.id, |this| {
18291790
intravisit::walk_item(this, item);
18301791
});
18311792
}
@@ -2261,7 +2222,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
22612222
// Move down in the graph, if there's an anonymous module rooted here.
22622223
let orig_module = self.current_module;
22632224
let anonymous_module =
2264-
orig_module.anonymous_children.borrow().get(&block.id).map(|module| *module);
2225+
orig_module.module_children.borrow().get(&block.id).map(|module| *module);
22652226

22662227
if let Some(anonymous_module) = anonymous_module {
22672228
debug!("(resolving block) found anonymous module, moving down");

src/librustc_resolve/resolve_imports.rs

+18-30
Original file line numberDiff line numberDiff line change
@@ -243,19 +243,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
243243
errors.extend(self.resolve_imports_for_module(module_));
244244
self.resolver.current_module = orig_module;
245245

246-
build_reduced_graph::populate_module_if_necessary(self.resolver, module_);
247-
module_.for_each_local_child(|_, _, child_node| {
248-
match child_node.module() {
249-
None => {
250-
// Nothing to do.
251-
}
252-
Some(child_module) => {
253-
errors.extend(self.resolve_imports_for_module_subtree(child_module));
254-
}
255-
}
256-
});
257-
258-
for (_, child_module) in module_.anonymous_children.borrow().iter() {
246+
for (_, child_module) in module_.module_children.borrow().iter() {
259247
errors.extend(self.resolve_imports_for_module_subtree(child_module));
260248
}
261249

@@ -403,6 +391,23 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
403391
module_.increment_outstanding_references_for(target, TypeNS);
404392
}
405393

394+
match (&value_result, &type_result) {
395+
(&Indeterminate, _) | (_, &Indeterminate) => return Indeterminate,
396+
(&Failed(_), &Failed(_)) => {
397+
let children = target_module.resolutions.borrow();
398+
let names = children.keys().map(|&(ref name, _)| name);
399+
let lev_suggestion = match find_best_match_for_name(names, &source.as_str(), None) {
400+
Some(name) => format!(". Did you mean to use `{}`?", name),
401+
None => "".to_owned(),
402+
};
403+
let msg = format!("There is no `{}` in `{}`{}",
404+
source,
405+
module_to_string(target_module), lev_suggestion);
406+
return Failed(Some((directive.span, msg)));
407+
}
408+
_ => (),
409+
}
410+
406411
match (&value_result, &type_result) {
407412
(&Success(name_binding), _) if !name_binding.is_import() &&
408413
directive.is_public &&
@@ -437,23 +442,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
437442
_ => {}
438443
}
439444

440-
match (&value_result, &type_result) {
441-
(&Indeterminate, _) | (_, &Indeterminate) => return Indeterminate,
442-
(&Failed(_), &Failed(_)) => {
443-
let children = target_module.children.borrow();
444-
let names = children.keys().map(|&(ref name, _)| name);
445-
let lev_suggestion = match find_best_match_for_name(names, &source.as_str(), None) {
446-
Some(name) => format!(". Did you mean to use `{}`?", name),
447-
None => "".to_owned(),
448-
};
449-
let msg = format!("There is no `{}` in `{}`{}",
450-
source,
451-
module_to_string(target_module), lev_suggestion);
452-
return Failed(Some((directive.span, msg)));
453-
}
454-
_ => (),
455-
}
456-
457445
for &(ns, result) in &[(ValueNS, &value_result), (TypeNS, &type_result)] {
458446
if let Success(binding) = *result {
459447
if !binding.defined_with(DefModifiers::IMPORTABLE) {

src/test/compile-fail/enum-and-module-in-same-scope.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
mod Foo {
12-
pub static X: isize = 42;
11+
enum Foo {
12+
X
1313
}
1414

15-
enum Foo { //~ ERROR duplicate definition of type or module `Foo`
16-
X
15+
mod Foo { //~ ERROR duplicate definition of type or module `Foo`
16+
pub static X: isize = 42;
17+
fn f() { f() } // Check that this does not result in a resolution error
1718
}
1819

1920
fn main() {}

0 commit comments

Comments
 (0)