Skip to content

Commit 27c4f9e

Browse files
committed
Fix a bug in which the visibility of a use declaration defining a name in one namespace (e.g. the value namespace) is overridden by a later use declaration defining the same name in the other namespace (e.g. the type namespace).
1 parent 81ae8be commit 27c4f9e

File tree

6 files changed

+153
-147
lines changed

6 files changed

+153
-147
lines changed

src/librustc_resolve/build_reduced_graph.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use DefModifiers;
1717
use resolve_imports::ImportDirective;
1818
use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport};
19-
use resolve_imports::ImportResolution;
19+
use resolve_imports::{ImportResolution, NsImportResolution};
2020
use Module;
2121
use Namespace::{TypeNS, ValueNS};
2222
use NameBindings;
@@ -827,9 +827,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
827827
resolution.outstanding_references += 1;
828828

829829
// the source of this name is different now
830-
resolution.type_id = id;
831-
resolution.value_id = id;
832-
resolution.is_public = is_public;
830+
let ns_resolution =
831+
NsImportResolution { id: id, is_public: is_public, target: None };
832+
resolution[TypeNS] = ns_resolution.clone();
833+
resolution[ValueNS] = ns_resolution;
833834
return;
834835
}
835836
None => {}

src/librustc_resolve/lib.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
328328
.import_resolutions
329329
.borrow()
330330
.get(&name) {
331-
let item = resolver.ast_map.expect_item(directive.value_id);
331+
let item = resolver.ast_map.expect_item(directive.value_ns.id);
332332
resolver.session.span_note(item.span, "constant imported here");
333333
}
334334
}
@@ -1491,7 +1491,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14911491
// adjacent import statements are processed as though they mutated the
14921492
// current scope.
14931493
if let Some(import_resolution) = module_.import_resolutions.borrow().get(&name) {
1494-
match (*import_resolution).target_for_namespace(namespace) {
1494+
match import_resolution[namespace].target.clone() {
14951495
None => {
14961496
// Not found; continue.
14971497
debug!("(resolving item in lexical scope) found import resolution, but not \
@@ -1501,7 +1501,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15011501
Some(target) => {
15021502
debug!("(resolving item in lexical scope) using import resolution");
15031503
// track used imports and extern crates as well
1504-
let id = import_resolution.id(namespace);
1504+
let id = import_resolution[namespace].id;
15051505
self.used_imports.insert((id, namespace));
15061506
self.record_import_use(id, name);
15071507
if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
@@ -1712,21 +1712,23 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
17121712

17131713
// Check the list of resolved imports.
17141714
match module_.import_resolutions.borrow().get(&name) {
1715-
Some(import_resolution) if allow_private_imports || import_resolution.is_public => {
1715+
Some(import_resolution) if allow_private_imports ||
1716+
import_resolution[namespace].is_public => {
17161717

1717-
if import_resolution.is_public && import_resolution.outstanding_references != 0 {
1718+
if import_resolution[namespace].is_public &&
1719+
import_resolution.outstanding_references != 0 {
17181720
debug!("(resolving name in module) import unresolved; bailing out");
17191721
return Indeterminate;
17201722
}
1721-
match import_resolution.target_for_namespace(namespace) {
1723+
match import_resolution[namespace].target.clone() {
17221724
None => {
17231725
debug!("(resolving name in module) name found, but not in namespace {:?}",
17241726
namespace);
17251727
}
17261728
Some(target) => {
17271729
debug!("(resolving name in module) resolved to import");
17281730
// track used imports and extern crates as well
1729-
let id = import_resolution.id(namespace);
1731+
let id = import_resolution[namespace].id;
17301732
self.used_imports.insert((id, namespace));
17311733
self.record_import_use(id, name);
17321734
if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
@@ -3651,17 +3653,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
36513653

36523654
// Look for imports.
36533655
for (_, import) in search_module.import_resolutions.borrow().iter() {
3654-
let target = match import.target_for_namespace(TypeNS) {
3656+
let target = match import.type_ns.target {
36553657
None => continue,
3656-
Some(target) => target,
3658+
Some(ref target) => target,
36573659
};
36583660
let did = match target.binding.def() {
36593661
Some(DefTrait(trait_def_id)) => trait_def_id,
36603662
Some(..) | None => continue,
36613663
};
36623664
if self.trait_item_map.contains_key(&(name, did)) {
36633665
add_trait_info(&mut found_traits, did, name);
3664-
let id = import.type_id;
3666+
let id = import.type_ns.id;
36653667
self.used_imports.insert((id, TypeNS));
36663668
let trait_name = self.get_trait_name(did);
36673669
self.record_import_use(id, trait_name);
@@ -3734,7 +3736,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
37343736
let import_resolutions = module_.import_resolutions.borrow();
37353737
for (&name, import_resolution) in import_resolutions.iter() {
37363738
let value_repr;
3737-
match import_resolution.target_for_namespace(ValueNS) {
3739+
match import_resolution.value_ns.target {
37383740
None => {
37393741
value_repr = "".to_string();
37403742
}
@@ -3745,7 +3747,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
37453747
}
37463748

37473749
let type_repr;
3748-
match import_resolution.target_for_namespace(TypeNS) {
3750+
match import_resolution.type_ns.target {
37493751
None => {
37503752
type_repr = "".to_string();
37513753
}

src/librustc_resolve/record_exports.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,14 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
130130

131131
fn add_exports_for_module(&mut self, exports: &mut Vec<Export>, module_: &Module) {
132132
for (name, import_resolution) in module_.import_resolutions.borrow().iter() {
133-
if !import_resolution.is_public {
134-
continue;
135-
}
136133
let xs = [TypeNS, ValueNS];
137134
for &ns in &xs {
138-
match import_resolution.target_for_namespace(ns) {
139-
Some(target) => {
135+
if !import_resolution[ns].is_public {
136+
continue;
137+
}
138+
139+
match import_resolution[ns].target {
140+
Some(ref target) => {
140141
debug!("(computing exports) maybe export '{}'", name);
141142
self.add_export_of_namebinding(exports, *name, &target.binding)
142143
}

0 commit comments

Comments
 (0)