Skip to content

Commit 5e67021

Browse files
committed
add typo suggestion to unknown attribute error
1 parent da6ab95 commit 5e67021

File tree

6 files changed

+108
-8
lines changed

6 files changed

+108
-8
lines changed

src/librustc_resolve/macros.rs

+65-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension};
1919
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
2020
use syntax::ext::hygiene::{self, Mark};
2121
use syntax::ext::tt::macro_rules;
22-
use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
22+
use syntax::feature_gate::{
23+
feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
24+
};
2325
use syntax::symbol::{Symbol, keywords};
2426
use syntax::visit::Visitor;
2527
use syntax::util::lev_distance::find_best_match_for_name;
@@ -310,15 +312,18 @@ impl<'a> Resolver<'a> {
310312
if !features.rustc_attrs {
311313
let msg = "unless otherwise specified, attributes with the prefix \
312314
`rustc_` are reserved for internal compiler diagnostics";
313-
feature_err(&self.session.parse_sess, "rustc_attrs", path.span,
314-
GateIssue::Language, &msg).emit();
315+
self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs");
315316
}
316317
} else if !features.custom_attribute {
317318
let msg = format!("The attribute `{}` is currently unknown to the \
318319
compiler and may have meaning added to it in the \
319320
future", path);
320-
feature_err(&self.session.parse_sess, "custom_attribute", path.span,
321-
GateIssue::Language, &msg).emit();
321+
self.report_unknown_attribute(
322+
path.span,
323+
&name,
324+
&msg,
325+
"custom_attribute",
326+
);
322327
}
323328
}
324329
} else {
@@ -339,6 +344,61 @@ impl<'a> Resolver<'a> {
339344
Ok((def, self.get_macro(def)))
340345
}
341346

347+
fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) {
348+
let mut err = feature_err(
349+
&self.session.parse_sess,
350+
feature,
351+
span,
352+
GateIssue::Language,
353+
&msg,
354+
);
355+
356+
let features = self.session.features_untracked();
357+
358+
let attr_candidates = BUILTIN_ATTRIBUTES
359+
.iter()
360+
.filter_map(|(name, _, _, gate)| {
361+
if name.starts_with("rustc_") && !features.rustc_attrs {
362+
return None;
363+
}
364+
365+
match gate {
366+
AttributeGate::Gated(Stability::Unstable, ..)
367+
if self.session.opts.unstable_features.is_nightly_build() =>
368+
{
369+
Some(name)
370+
}
371+
AttributeGate::Gated(Stability::Deprecated(..), ..) => Some(name),
372+
AttributeGate::Ungated => Some(name),
373+
_ => None,
374+
}
375+
})
376+
.map(|name| Symbol::intern(name))
377+
.chain(
378+
// Add built-in macro attributes as well.
379+
self.builtin_macros.iter().filter_map(|(name, binding)| {
380+
match binding.macro_kind() {
381+
Some(MacroKind::Attr) => Some(*name),
382+
_ => None,
383+
}
384+
}),
385+
)
386+
.collect::<Vec<_>>();
387+
388+
let lev_suggestion = find_best_match_for_name(attr_candidates.iter(), &name, None);
389+
390+
if let Some(suggestion) = lev_suggestion {
391+
err.span_suggestion(
392+
span,
393+
"a built-in attribute with a similar name exists",
394+
suggestion.to_string(),
395+
Applicability::MaybeIncorrect,
396+
);
397+
}
398+
399+
err.emit();
400+
}
401+
342402
pub fn resolve_macro_to_def_inner(
343403
&mut self,
344404
path: &ast::Path,

src/test/ui/issues/issue-49074.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0658]: The attribute `marco_use` is currently unknown to the compiler and
22
--> $DIR/issue-49074.rs:3:3
33
|
44
LL | #[marco_use] // typo
5-
| ^^^^^^^^^
5+
| ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use`
66
|
77
= help: add #![feature(custom_attribute)] to the crate attributes to enable
88

src/test/ui/macros/macro-reexport-removed.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ error[E0658]: The attribute `macro_reexport` is currently unknown to the compile
1414
--> $DIR/macro-reexport-removed.rs:5:3
1515
|
1616
LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
17-
| ^^^^^^^^^^^^^^
17+
| ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export`
1818
|
1919
= help: add #![feature(custom_attribute)] to the crate attributes to enable
2020

src/test/ui/proc-macro/derive-still-gated.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0658]: The attribute `derive_A` is currently unknown to the compiler and
22
--> $DIR/derive-still-gated.rs:8:3
33
|
44
LL | #[derive_A] //~ ERROR attribute `derive_A` is currently unknown
5-
| ^^^^^^^^
5+
| ^^^^^^^^ help: a built-in attribute with a similar name exists: `derive`
66
|
77
= help: add #![feature(custom_attribute)] to the crate attributes to enable
88

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#[deprcated] //~ ERROR E0658
2+
fn foo() {} //~| HELP a built-in attribute with a similar name exists
3+
//~| SUGGESTION deprecated
4+
//~| HELP add #![feature(custom_attribute)] to the crate attributes to enable
5+
6+
#[tests] //~ ERROR E0658
7+
fn bar() {} //~| HELP a built-in attribute with a similar name exists
8+
//~| SUGGESTION test
9+
//~| HELP add #![feature(custom_attribute)] to the crate attributes to enable
10+
11+
#[rustc_err] //~ ERROR E0658
12+
fn main() {} //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable
13+
// don't suggest rustc attributes
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642)
2+
--> $DIR/attribute-typos.rs:11:3
3+
|
4+
LL | #[rustc_err] //~ ERROR E0658
5+
| ^^^^^^^^^
6+
|
7+
= help: add #![feature(rustc_attrs)] to the crate attributes to enable
8+
9+
error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
10+
--> $DIR/attribute-typos.rs:6:3
11+
|
12+
LL | #[tests] //~ ERROR E0658
13+
| ^^^^^ help: a built-in attribute with a similar name exists: `test`
14+
|
15+
= help: add #![feature(custom_attribute)] to the crate attributes to enable
16+
17+
error[E0658]: The attribute `deprcated` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
18+
--> $DIR/attribute-typos.rs:1:3
19+
|
20+
LL | #[deprcated] //~ ERROR E0658
21+
| ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated`
22+
|
23+
= help: add #![feature(custom_attribute)] to the crate attributes to enable
24+
25+
error: aborting due to 3 previous errors
26+
27+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)