Skip to content

Commit 32a0cfe

Browse files
committed
Avoid reporting multiple ambiguity errors for a single use of a name.
1 parent 681a14f commit 32a0cfe

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

src/librustc_resolve/lib.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ pub struct Resolver<'a> {
10651065
pub maybe_unused_trait_imports: NodeSet,
10661066

10671067
privacy_errors: Vec<PrivacyError<'a>>,
1068+
ambiguity_errors: Vec<(Span, Name, &'a NameBinding<'a>)>,
10681069

10691070
arenas: &'a ResolverArenas<'a>,
10701071
dummy_binding: &'a NameBinding<'a>,
@@ -1218,6 +1219,7 @@ impl<'a> Resolver<'a> {
12181219
maybe_unused_trait_imports: NodeSet(),
12191220

12201221
privacy_errors: Vec::new(),
1222+
ambiguity_errors: Vec::new(),
12211223

12221224
arenas: arenas,
12231225
dummy_binding: arenas.alloc_name_binding(NameBinding {
@@ -1245,7 +1247,7 @@ impl<'a> Resolver<'a> {
12451247
visit::walk_crate(self, krate);
12461248

12471249
check_unused::check_crate(self, krate);
1248-
self.report_privacy_errors();
1250+
self.report_errors();
12491251
}
12501252

12511253
fn new_module(&self, parent_link: ParentLink<'a>, def: Option<Def>, normal_ancestor_id: NodeId)
@@ -1276,14 +1278,8 @@ impl<'a> Resolver<'a> {
12761278
self.add_to_glob_map(directive.id, name);
12771279
}
12781280

1279-
if let Some((b1, b2)) = binding.ambiguity() {
1280-
let msg1 = format!("`{}` could resolve to the name imported here", name);
1281-
let msg2 = format!("`{}` could also resolve to the name imported here", name);
1282-
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
1283-
.span_note(b1.span, &msg1)
1284-
.span_note(b2.span, &msg2)
1285-
.note(&format!("Consider adding an explicit import of `{}` to disambiguate", name))
1286-
.emit();
1281+
if binding.ambiguity().is_some() {
1282+
self.ambiguity_errors.push((span, name, binding));
12871283
return true;
12881284
}
12891285

@@ -3289,9 +3285,21 @@ impl<'a> Resolver<'a> {
32893285
vis.is_accessible_from(module.normal_ancestor_id, self)
32903286
}
32913287

3292-
fn report_privacy_errors(&self) {
3293-
if self.privacy_errors.len() == 0 { return }
3288+
fn report_errors(&self) {
32943289
let mut reported_spans = FnvHashSet();
3290+
3291+
for &(span, name, binding) in &self.ambiguity_errors {
3292+
if !reported_spans.insert(span) { continue }
3293+
let (b1, b2) = binding.ambiguity().unwrap();
3294+
let msg1 = format!("`{}` could resolve to the name imported here", name);
3295+
let msg2 = format!("`{}` could also resolve to the name imported here", name);
3296+
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
3297+
.span_note(b1.span, &msg1)
3298+
.span_note(b2.span, &msg2)
3299+
.note(&format!("Consider adding an explicit import of `{}` to disambiguate", name))
3300+
.emit();
3301+
}
3302+
32953303
for &PrivacyError(span, name, binding) in &self.privacy_errors {
32963304
if !reported_spans.insert(span) { continue }
32973305
if binding.is_extern_crate() {

src/test/compile-fail/imports/duplicate.rs

+13
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,16 @@ fn main() {
5050
g::foo(); //~ ERROR `foo` is ambiguous
5151
//~| NOTE Consider adding an explicit import of `foo` to disambiguate
5252
}
53+
54+
mod ambiguous_module_errors {
55+
pub mod m1 { pub use super::m1 as foo; }
56+
pub mod m2 { pub use super::m2 as foo; }
57+
58+
use self::m1::*; //~ NOTE
59+
use self::m2::*; //~ NOTE
60+
61+
fn f() {
62+
foo::bar(); //~ ERROR `foo` is ambiguous
63+
//~| NOTE
64+
}
65+
}

0 commit comments

Comments
 (0)