Skip to content

Commit 514c6b6

Browse files
committed
rustc_resolve: don't treat uniform_paths canaries as ambiguities unless they resolve to distinct Def's.
1 parent 84c36a1 commit 514c6b6

File tree

3 files changed

+32
-26
lines changed

3 files changed

+32
-26
lines changed

src/librustc_resolve/resolve_imports.rs

+16-26
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
730730
let external_crate = if ns == TypeNS && self.extern_prelude.contains(&name) {
731731
let crate_id =
732732
self.crate_loader.process_path_extern(name, span);
733-
Some(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
733+
Some(Def::Mod(DefId { krate: crate_id, index: CRATE_DEF_INDEX }))
734734
} else {
735735
None
736736
};
@@ -741,30 +741,20 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
741741
return;
742742
}
743743

744-
let result_filter = |result: &&NameBinding| {
745-
// Ignore canaries that resolve to an import of the same crate.
746-
// That is, we allow `use crate_name; use crate_name::foo;`.
747-
if let Some(def_id) = external_crate {
748-
if let Some(module) = result.module() {
749-
if module.normal_ancestor_id == def_id {
750-
return false;
751-
}
752-
}
744+
{
745+
let mut all_results = external_crate.into_iter().chain(
746+
results.module_scope.iter()
747+
.chain(&results.block_scopes)
748+
.map(|binding| binding.def())
749+
);
750+
let first = all_results.next().unwrap();
751+
752+
// An ambiguity requires more than one *distinct* possible resolution.
753+
let possible_resultions =
754+
1 + all_results.filter(|&def| def != first).count();
755+
if possible_resultions <= 1 {
756+
return;
753757
}
754-
755-
true
756-
};
757-
let module_scope = results.module_scope.filter(result_filter);
758-
let block_scopes = || {
759-
results.block_scopes.iter().cloned().filter(result_filter)
760-
};
761-
762-
// An ambiguity requires more than one possible resolution.
763-
let possible_resultions =
764-
(external_crate.is_some() as usize) +
765-
module_scope.into_iter().chain(block_scopes()).count();
766-
if possible_resultions <= 1 {
767-
return;
768758
}
769759

770760
errors = true;
@@ -777,7 +767,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
777767
err.span_label(span,
778768
format!("can refer to external crate `::{}`", name));
779769
}
780-
if let Some(result) = module_scope {
770+
if let Some(result) = results.module_scope {
781771
if !suggestion_choices.is_empty() {
782772
suggestion_choices.push_str(" or ");
783773
}
@@ -790,7 +780,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
790780
format!("may refer to `self::{}` in the future", name));
791781
}
792782
}
793-
for result in block_scopes() {
783+
for result in results.block_scopes {
794784
err.span_label(result.span,
795785
format!("shadowed by block-scoped `{}`", name));
796786
}

src/test/ui/run-pass/uniform-paths/basic-nested.rs

+8
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,12 @@ fn main() {
5959
bar::io::stdout();
6060
bar::std();
6161
bar::std!();
62+
63+
{
64+
// Test that having `io` in a module scope and a non-module
65+
// scope is allowed, when both resolve to the same definition.
66+
use std::io;
67+
use io::stdout;
68+
stdout();
69+
}
6270
}

src/test/ui/run-pass/uniform-paths/basic.rs

+8
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,12 @@ fn main() {
3333
Foo(());
3434
std_io::stdout();
3535
local_io(());
36+
37+
{
38+
// Test that having `std_io` in a module scope and a non-module
39+
// scope is allowed, when both resolve to the same definition.
40+
use std::io as std_io;
41+
use std_io::stdout;
42+
stdout();
43+
}
3644
}

0 commit comments

Comments
 (0)