Skip to content

Commit

Permalink
add typo suggestion to unknown attribute error
Browse files Browse the repository at this point in the history
  • Loading branch information
euclio committed Jan 28, 2019
1 parent da6ab95 commit 5e67021
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 8 deletions.
70 changes: 65 additions & 5 deletions src/librustc_resolve/macros.rs
Expand Up @@ -19,7 +19,9 @@ use syntax::ext::base::{Annotatable, MacroKind, SyntaxExtension};
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
use syntax::ext::hygiene::{self, Mark};
use syntax::ext::tt::macro_rules;
use syntax::feature_gate::{feature_err, is_builtin_attr_name, GateIssue};
use syntax::feature_gate::{
feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
};
use syntax::symbol::{Symbol, keywords};
use syntax::visit::Visitor;
use syntax::util::lev_distance::find_best_match_for_name;
Expand Down Expand Up @@ -310,15 +312,18 @@ impl<'a> Resolver<'a> {
if !features.rustc_attrs {
let msg = "unless otherwise specified, attributes with the prefix \
`rustc_` are reserved for internal compiler diagnostics";
feature_err(&self.session.parse_sess, "rustc_attrs", path.span,
GateIssue::Language, &msg).emit();
self.report_unknown_attribute(path.span, &name, msg, "rustc_attrs");
}
} else if !features.custom_attribute {
let msg = format!("The attribute `{}` is currently unknown to the \
compiler and may have meaning added to it in the \
future", path);
feature_err(&self.session.parse_sess, "custom_attribute", path.span,
GateIssue::Language, &msg).emit();
self.report_unknown_attribute(
path.span,
&name,
&msg,
"custom_attribute",
);
}
}
} else {
Expand All @@ -339,6 +344,61 @@ impl<'a> Resolver<'a> {
Ok((def, self.get_macro(def)))
}

fn report_unknown_attribute(&self, span: Span, name: &str, msg: &str, feature: &str) {
let mut err = feature_err(
&self.session.parse_sess,
feature,
span,
GateIssue::Language,
&msg,
);

let features = self.session.features_untracked();

let attr_candidates = BUILTIN_ATTRIBUTES
.iter()
.filter_map(|(name, _, _, gate)| {
if name.starts_with("rustc_") && !features.rustc_attrs {
return None;
}

match gate {
AttributeGate::Gated(Stability::Unstable, ..)
if self.session.opts.unstable_features.is_nightly_build() =>
{
Some(name)
}
AttributeGate::Gated(Stability::Deprecated(..), ..) => Some(name),
AttributeGate::Ungated => Some(name),
_ => None,
}
})
.map(|name| Symbol::intern(name))
.chain(
// Add built-in macro attributes as well.
self.builtin_macros.iter().filter_map(|(name, binding)| {
match binding.macro_kind() {
Some(MacroKind::Attr) => Some(*name),
_ => None,
}
}),
)
.collect::<Vec<_>>();

let lev_suggestion = find_best_match_for_name(attr_candidates.iter(), &name, None);

if let Some(suggestion) = lev_suggestion {
err.span_suggestion(
span,
"a built-in attribute with a similar name exists",
suggestion.to_string(),
Applicability::MaybeIncorrect,
);
}

err.emit();
}

pub fn resolve_macro_to_def_inner(
&mut self,
path: &ast::Path,
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-49074.stderr
Expand Up @@ -2,7 +2,7 @@ error[E0658]: The attribute `marco_use` is currently unknown to the compiler and
--> $DIR/issue-49074.rs:3:3
|
LL | #[marco_use] // typo
| ^^^^^^^^^
| ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/macros/macro-reexport-removed.stderr
Expand Up @@ -14,7 +14,7 @@ error[E0658]: The attribute `macro_reexport` is currently unknown to the compile
--> $DIR/macro-reexport-removed.rs:5:3
|
LL | #[macro_reexport(macro_one)] //~ ERROR attribute `macro_reexport` is currently unknown
| ^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/proc-macro/derive-still-gated.stderr
Expand Up @@ -2,7 +2,7 @@ error[E0658]: The attribute `derive_A` is currently unknown to the compiler and
--> $DIR/derive-still-gated.rs:8:3
|
LL | #[derive_A] //~ ERROR attribute `derive_A` is currently unknown
| ^^^^^^^^
| ^^^^^^^^ help: a built-in attribute with a similar name exists: `derive`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/suggestions/attribute-typos.rs
@@ -0,0 +1,13 @@
#[deprcated] //~ ERROR E0658
fn foo() {} //~| HELP a built-in attribute with a similar name exists
//~| SUGGESTION deprecated
//~| HELP add #![feature(custom_attribute)] to the crate attributes to enable

#[tests] //~ ERROR E0658
fn bar() {} //~| HELP a built-in attribute with a similar name exists
//~| SUGGESTION test
//~| HELP add #![feature(custom_attribute)] to the crate attributes to enable

#[rustc_err] //~ ERROR E0658
fn main() {} //~| HELP add #![feature(rustc_attrs)] to the crate attributes to enable
// don't suggest rustc attributes
27 changes: 27 additions & 0 deletions src/test/ui/suggestions/attribute-typos.stderr
@@ -0,0 +1,27 @@
error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642)
--> $DIR/attribute-typos.rs:11:3
|
LL | #[rustc_err] //~ ERROR E0658
| ^^^^^^^^^
|
= help: add #![feature(rustc_attrs)] to the crate attributes to enable

error[E0658]: The attribute `tests` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/attribute-typos.rs:6:3
|
LL | #[tests] //~ ERROR E0658
| ^^^^^ help: a built-in attribute with a similar name exists: `test`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error[E0658]: The attribute `deprcated` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> $DIR/attribute-typos.rs:1:3
|
LL | #[deprcated] //~ ERROR E0658
| ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated`
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.

0 comments on commit 5e67021

Please sign in to comment.