mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
suggest similar lint names for unknown lints
This commit is contained in:
parent
adbfec229c
commit
90726e1ac1
@ -42,11 +42,12 @@ use util::nodemap::FxHashMap;
|
||||
use std::default::Default as StdDefault;
|
||||
use syntax::ast;
|
||||
use syntax::edition;
|
||||
use syntax_pos::{MultiSpan, Span, symbol::LocalInternedString};
|
||||
use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
|
||||
use errors::DiagnosticBuilder;
|
||||
use hir;
|
||||
use hir::def_id::LOCAL_CRATE;
|
||||
use hir::intravisit as hir_visit;
|
||||
use syntax::util::lev_distance::find_best_match_for_name;
|
||||
use syntax::visit as ast_visit;
|
||||
|
||||
/// Information about the registered lints.
|
||||
@ -139,8 +140,8 @@ struct LintGroup {
|
||||
|
||||
pub enum CheckLintNameResult<'a> {
|
||||
Ok(&'a [LintId]),
|
||||
/// Lint doesn't exist
|
||||
NoLint,
|
||||
/// Lint doesn't exist. Potentially contains a suggestion for a correct lint name.
|
||||
NoLint(Option<Symbol>),
|
||||
/// The lint is either renamed or removed. This is the warning
|
||||
/// message, and an optional new name (`None` if removed).
|
||||
Warning(String, Option<String>),
|
||||
@ -359,8 +360,14 @@ impl LintStore {
|
||||
CheckLintNameResult::Warning(ref msg, _) => {
|
||||
Some(sess.struct_warn(msg))
|
||||
},
|
||||
CheckLintNameResult::NoLint => {
|
||||
Some(struct_err!(sess, E0602, "unknown lint: `{}`", lint_name))
|
||||
CheckLintNameResult::NoLint(suggestion) => {
|
||||
let mut err = struct_err!(sess, E0602, "unknown lint: `{}`", lint_name);
|
||||
|
||||
if let Some(suggestion) = suggestion {
|
||||
err.help(&format!("did you mean: `{}`", suggestion));
|
||||
}
|
||||
|
||||
Some(err)
|
||||
}
|
||||
CheckLintNameResult::Tool(result) => match result {
|
||||
Err((Some(_), new_name)) => Some(sess.struct_warn(&format!(
|
||||
@ -464,7 +471,16 @@ impl LintStore {
|
||||
match self.by_name.get(&complete_name) {
|
||||
None => match self.lint_groups.get(&*complete_name) {
|
||||
// Now we are sure, that this lint exists nowhere
|
||||
None => CheckLintNameResult::NoLint,
|
||||
None => {
|
||||
let symbols = self.by_name.keys()
|
||||
.map(|name| Symbol::intern(&name))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let suggestion =
|
||||
find_best_match_for_name(symbols.iter(), &lint_name.to_lowercase(), None);
|
||||
|
||||
CheckLintNameResult::NoLint(suggestion)
|
||||
}
|
||||
Some(LintGroup { lint_ids, depr, .. }) => {
|
||||
// Reaching this would be weird, but let's cover this case anyway
|
||||
if let Some(LintAlias { name, silent }) = depr {
|
||||
@ -484,7 +500,7 @@ impl LintStore {
|
||||
Some(&Id(ref id)) => {
|
||||
CheckLintNameResult::Tool(Err((Some(slice::from_ref(id)), complete_name)))
|
||||
}
|
||||
_ => CheckLintNameResult::NoLint,
|
||||
_ => CheckLintNameResult::NoLint(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ impl<'a> LintLevelsBuilder<'a> {
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
CheckLintNameResult::NoLint => {
|
||||
CheckLintNameResult::NoLint(suggestion) => {
|
||||
let lint = builtin::UNKNOWN_LINTS;
|
||||
let (level, src) = self.sets.get_lint_level(lint,
|
||||
self.cur,
|
||||
@ -398,26 +398,21 @@ impl<'a> LintLevelsBuilder<'a> {
|
||||
src,
|
||||
Some(li.span.into()),
|
||||
&msg);
|
||||
if name.as_str().chars().any(|c| c.is_uppercase()) {
|
||||
let name_lower = name.as_str().to_lowercase().to_string();
|
||||
if let CheckLintNameResult::NoLint =
|
||||
store.check_lint_name(&name_lower, tool_name) {
|
||||
db.emit();
|
||||
} else {
|
||||
|
||||
if let Some(suggestion) = suggestion {
|
||||
db.span_suggestion_with_applicability(
|
||||
li.span,
|
||||
"lowercase the lint name",
|
||||
name_lower,
|
||||
Applicability::MachineApplicable
|
||||
).emit();
|
||||
"did you mean",
|
||||
suggestion.to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
db.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (id, &(level, ref src)) in specs.iter() {
|
||||
if level == Level::Forbid {
|
||||
|
@ -8,9 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags:-D bogus
|
||||
// compile-flags:-D bogus -D dead_cod
|
||||
|
||||
// error-pattern:unknown lint
|
||||
// error-pattern:unknown lint: `bogus`
|
||||
// error-pattern:requested on the command line with `-D bogus`
|
||||
// error-pattern:unknown lint: `dead_cod`
|
||||
// error-pattern:requested on the command line with `-D dead_cod`
|
||||
// error-pattern:did you mean: `dead_code`
|
||||
|
||||
fn main() { }
|
||||
|
@ -2,6 +2,11 @@ error[E0602]: unknown lint: `bogus`
|
||||
|
|
||||
= note: requested on the command line with `-D bogus`
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0602]: unknown lint: `dead_cod`
|
||||
|
|
||||
= help: did you mean: `dead_code`
|
||||
= note: requested on the command line with `-D dead_cod`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0602`.
|
||||
|
@ -8,6 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(not_a_real_lint)] //~ WARN unknown lint
|
||||
#![deny(unused)]
|
||||
fn main() { let unused = (); } //~ ERROR unused variable
|
||||
#![deny(unknown_lints)]
|
||||
|
||||
#![allow(not_a_real_lint)] //~ ERROR unknown lint
|
||||
|
||||
#![deny(dead_cod)] //~ ERROR unknown lint
|
||||
//~| HELP did you mean
|
||||
//~| SUGGESTION dead_code
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,23 +1,20 @@
|
||||
warning: unknown lint: `not_a_real_lint`
|
||||
--> $DIR/lint-unknown-lint.rs:11:10
|
||||
error: unknown lint: `not_a_real_lint`
|
||||
--> $DIR/lint-unknown-lint.rs:13:10
|
||||
|
|
||||
LL | #![allow(not_a_real_lint)] //~ WARN unknown lint
|
||||
LL | #![allow(not_a_real_lint)] //~ ERROR unknown lint
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: #[warn(unknown_lints)] on by default
|
||||
|
||||
error: unused variable: `unused`
|
||||
--> $DIR/lint-unknown-lint.rs:13:17
|
||||
|
|
||||
LL | fn main() { let unused = (); } //~ ERROR unused variable
|
||||
| ^^^^^^ help: consider using `_unused` instead
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/lint-unknown-lint.rs:12:9
|
||||
--> $DIR/lint-unknown-lint.rs:11:9
|
||||
|
|
||||
LL | #![deny(unused)]
|
||||
| ^^^^^^
|
||||
= note: #[deny(unused_variables)] implied by #[deny(unused)]
|
||||
LL | #![deny(unknown_lints)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error: unknown lint: `dead_cod`
|
||||
--> $DIR/lint-unknown-lint.rs:15:9
|
||||
|
|
||||
LL | #![deny(dead_cod)] //~ ERROR unknown lint
|
||||
| ^^^^^^^^ help: did you mean: `dead_code`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -10,11 +10,11 @@ warning: unknown lint: `DEAD_CODE`
|
||||
--> $DIR/not_found.rs:18:8
|
||||
|
|
||||
LL | #[warn(DEAD_CODE)]
|
||||
| ^^^^^^^^^ help: lowercase the lint name: `dead_code`
|
||||
| ^^^^^^^^^ help: did you mean: `dead_code`
|
||||
|
||||
warning: unknown lint: `Warnings`
|
||||
--> $DIR/not_found.rs:20:8
|
||||
|
|
||||
LL | #[deny(Warnings)]
|
||||
| ^^^^^^^^ help: lowercase the lint name: `warnings`
|
||||
| ^^^^^^^^ help: did you mean: `warnings`
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user