Skip to content

Commit 82619ea

Browse files
committed
resolve: Unify reporting of ambiguity errors for macro paths
1 parent c2788a8 commit 82619ea

File tree

5 files changed

+68
-43
lines changed

5 files changed

+68
-43
lines changed

src/librustc_resolve/lib.rs

+45-24
Original file line numberDiff line numberDiff line change
@@ -4431,6 +4431,42 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
44314431
vis.is_accessible_from(module.normal_ancestor_id, self)
44324432
}
44334433

4434+
fn report_ambiguity_error(
4435+
&self, name: Name, span: Span, _lexical: bool,
4436+
def1: Def, is_import1: bool, is_glob1: bool, from_expansion1: bool, span1: Span,
4437+
def2: Def, is_import2: bool, _is_glob2: bool, _from_expansion2: bool, span2: Span,
4438+
) {
4439+
let participle = |is_import: bool| if is_import { "imported" } else { "defined" };
4440+
let msg1 = format!("`{}` could refer to the name {} here", name, participle(is_import1));
4441+
let msg2 =
4442+
format!("`{}` could also refer to the name {} here", name, participle(is_import2));
4443+
let note = if from_expansion1 {
4444+
Some(if let Def::Macro(..) = def1 {
4445+
format!("macro-expanded {} do not shadow",
4446+
if is_import1 { "macro imports" } else { "macros" })
4447+
} else {
4448+
format!("macro-expanded {} do not shadow when used in a macro invocation path",
4449+
if is_import1 { "imports" } else { "items" })
4450+
})
4451+
} else if is_glob1 {
4452+
Some(format!("consider adding an explicit import of `{}` to disambiguate", name))
4453+
} else {
4454+
None
4455+
};
4456+
4457+
let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name);
4458+
err.span_note(span1, &msg1);
4459+
match def2 {
4460+
Def::Macro(..) if span2.is_dummy() =>
4461+
err.note(&format!("`{}` is also a builtin macro", name)),
4462+
_ => err.span_note(span2, &msg2),
4463+
};
4464+
if let Some(note) = note {
4465+
err.note(&note);
4466+
}
4467+
err.emit();
4468+
}
4469+
44344470
fn report_errors(&mut self, krate: &Crate) {
44354471
self.report_shadowing_errors();
44364472
self.report_with_use_injections(krate);
@@ -4446,30 +4482,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
44464482
}
44474483

44484484
for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors {
4449-
if !reported_spans.insert(span) { continue }
4450-
let participle = |binding: &NameBinding| {
4451-
if binding.is_import() { "imported" } else { "defined" }
4452-
};
4453-
let msg1 = format!("`{}` could refer to the name {} here", name, participle(b1));
4454-
let msg2 = format!("`{}` could also refer to the name {} here", name, participle(b2));
4455-
let note = if b1.expansion == Mark::root() || !lexical && b1.is_glob_import() {
4456-
format!("consider adding an explicit import of `{}` to disambiguate", name)
4457-
} else if let Def::Macro(..) = b1.def() {
4458-
format!("macro-expanded {} do not shadow",
4459-
if b1.is_import() { "macro imports" } else { "macros" })
4460-
} else {
4461-
format!("macro-expanded {} do not shadow when used in a macro invocation path",
4462-
if b1.is_import() { "imports" } else { "items" })
4463-
};
4464-
4465-
let mut err = struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name);
4466-
err.span_note(b1.span, &msg1);
4467-
match b2.def() {
4468-
Def::Macro(..) if b2.span.is_dummy() =>
4469-
err.note(&format!("`{}` is also a builtin macro", name)),
4470-
_ => err.span_note(b2.span, &msg2),
4471-
};
4472-
err.note(&note).emit();
4485+
if reported_spans.insert(span) {
4486+
self.report_ambiguity_error(
4487+
name, span, lexical,
4488+
b1.def(), b1.is_import(), b1.is_glob_import(),
4489+
b1.expansion != Mark::root(), b1.span,
4490+
b2.def(), b2.is_import(), b2.is_glob_import(),
4491+
b2.expansion != Mark::root(), b2.span,
4492+
);
4493+
}
44734494
}
44744495

44754496
for &PrivacyError(span, name, binding) in &self.privacy_errors {

src/librustc_resolve/macros.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -871,16 +871,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
871871
self.suggest_macro_name(&ident.as_str(), kind, &mut err, span);
872872
err.emit();
873873
},
874-
(Some((legacy_binding, _)), Ok((binding, FromPrelude(false)))) |
875-
(Some((legacy_binding, FromExpansion(true))), Ok((binding, FromPrelude(true)))) => {
874+
(Some((legacy_binding, FromExpansion(from_expansion))),
875+
Ok((binding, FromPrelude(false)))) |
876+
(Some((legacy_binding, FromExpansion(from_expansion @ true))),
877+
Ok((binding, FromPrelude(true)))) => {
876878
if legacy_binding.def() != binding.def_ignoring_ambiguity() {
877-
let msg1 = format!("`{}` could refer to the macro defined here", ident);
878-
let msg2 =
879-
format!("`{}` could also refer to the macro imported here", ident);
880-
self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
881-
.span_note(legacy_binding.span, &msg1)
882-
.span_note(binding.span, &msg2)
883-
.emit();
879+
self.report_ambiguity_error(
880+
ident.name, span, true,
881+
legacy_binding.def(), false, false,
882+
from_expansion, legacy_binding.span,
883+
binding.def(), binding.is_import(), binding.is_glob_import(),
884+
binding.expansion != Mark::root(), binding.span,
885+
);
884886
}
885887
},
886888
// OK, non-macro-expanded legacy wins over macro prelude even if defs are different

src/test/ui/imports/issue-53269.stderr

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,24 @@ error[E0432]: unresolved import `nonexistent_module`
44
LL | use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
55
| ^^^^^^^^^^^^^^^^^^ Maybe a missing `extern crate nonexistent_module;`?
66

7-
error: `mac` is ambiguous
7+
error[E0659]: `mac` is ambiguous
88
--> $DIR/issue-53269.rs:18:5
99
|
1010
LL | mac!(); //~ ERROR `mac` is ambiguous
1111
| ^^^
1212
|
13-
note: `mac` could refer to the macro defined here
13+
note: `mac` could refer to the name defined here
1414
--> $DIR/issue-53269.rs:13:1
1515
|
1616
LL | macro_rules! mac { () => () }
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18-
note: `mac` could also refer to the macro imported here
18+
note: `mac` could also refer to the name imported here
1919
--> $DIR/issue-53269.rs:16:9
2020
|
2121
LL | use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
2222
| ^^^^^^^^^^^^^^^^^^^^^^^
2323

2424
error: aborting due to 2 previous errors
2525

26-
For more information about this error, try `rustc --explain E0432`.
26+
Some errors occurred: E0432, E0659.
27+
For more information about an error, try `rustc --explain E0432`.

src/test/ui/imports/macros.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
error: `m` is ambiguous
1+
error[E0659]: `m` is ambiguous
22
--> $DIR/macros.rs:48:5
33
|
44
LL | m!(); //~ ERROR ambiguous
55
| ^
66
|
7-
note: `m` could refer to the macro defined here
7+
note: `m` could refer to the name defined here
88
--> $DIR/macros.rs:46:5
99
|
1010
LL | macro_rules! m { () => {} }
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
note: `m` could also refer to the macro imported here
12+
note: `m` could also refer to the name imported here
1313
--> $DIR/macros.rs:47:9
1414
|
1515
LL | use two_macros::m;

src/test/ui/imports/shadow_builtin_macros.stderr

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
error: `panic` is ambiguous
1+
error[E0659]: `panic` is ambiguous
22
--> $DIR/shadow_builtin_macros.rs:43:5
33
|
44
LL | panic!(); //~ ERROR `panic` is ambiguous
55
| ^^^^^
66
|
7-
note: `panic` could refer to the macro defined here
7+
note: `panic` could refer to the name defined here
88
--> $DIR/shadow_builtin_macros.rs:40:9
99
|
1010
LL | macro_rules! panic { () => {} }
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
LL | } }
1313
LL | m!();
1414
| ----- in this macro invocation
15-
note: `panic` could also refer to the macro imported here
15+
= note: `panic` is also a builtin macro
16+
= note: macro-expanded macros do not shadow
1617

1718
error[E0659]: `panic` is ambiguous
1819
--> $DIR/shadow_builtin_macros.rs:25:14

0 commit comments

Comments
 (0)