add typo suggestion to unknown attribute error
This commit is contained in:
parent
da6ab956e1
commit
5e67021172
@ -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;
|
||||
@ -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 {
|
||||
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
13
src/test/ui/suggestions/attribute-typos.rs
Normal file
13
src/test/ui/suggestions/attribute-typos.rs
Normal file
@ -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
src/test/ui/suggestions/attribute-typos.stderr
Normal file
27
src/test/ui/suggestions/attribute-typos.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user