Migrate irrefutable let pattern diagnostics

This commit is contained in:
TheOddGarlic 2022-08-29 11:21:25 +03:00 committed by mejrs
parent e1c5073c07
commit eeef05b318
3 changed files with 103 additions and 57 deletions

View File

@ -237,3 +237,53 @@ mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count ->
mir_build_bindings_with_variant_name =
pattern binding `{$ident}` is named the same as one of the variants of the type `{$ty_path}`
.suggestion = to match on the variant, qualify the path
mir_build_irrefutable_let_patterns_generic_let = irrefutable `let` {$count ->
[one] pattern
*[other] patterns
}
.note = {$count ->
[one] this pattern
*[other] these patterns
} will always match, so the `let` is useless
.help = consider removing `let`
mir_build_irrefutable_let_patterns_if_let = irrefutable `if let` {$count ->
[one] pattern
*[other] patterns
}
.note = {$count ->
[one] this pattern
*[other] these patterns
} will always match, so the `if let` is useless
.help = consider replacing the `if let` with a `let`
mir_build_irrefutable_let_patterns_if_let_guard = irrefutable `if let` guard {$count ->
[one] pattern
*[other] patterns
}
.note = {$count ->
[one] this pattern
*[other] these patterns
} will always match, so the guard is useless
.help = consider removing the guard and adding a `let` inside the match arm
mir_build_irrefutable_let_patterns_let_else = irrefutable `let...else` {$count ->
[one] pattern
*[other] patterns
}
.note = {$count ->
[one] this pattern
*[other] these patterns
} will always match, so the `else` clause is useless
.help = consider removing the `else` clause
mir_build_irrefutable_let_patterns_while_let = irrefutable `while let` {$count ->
[one] pattern
*[other] patterns
}
.note = {$count ->
[one] this pattern
*[other] these patterns
} will always match, so the loop will never exit
.help = consider instead using a `loop {"{"} ... {"}"}` with a `let` inside it

View File

@ -522,3 +522,43 @@ pub struct BindingsWithVariantName {
pub ty_path: String,
pub ident: Ident,
}
#[derive(LintDiagnostic)]
#[diag(mir_build::irrefutable_let_patterns_generic_let)]
#[note]
#[help]
pub struct IrrefutableLetPatternsGenericLet {
pub count: usize,
}
#[derive(LintDiagnostic)]
#[diag(mir_build::irrefutable_let_patterns_if_let)]
#[note]
#[help]
pub struct IrrefutableLetPatternsIfLet {
pub count: usize,
}
#[derive(LintDiagnostic)]
#[diag(mir_build::irrefutable_let_patterns_if_let_guard)]
#[note]
#[help]
pub struct IrrefutableLetPatternsIfLetGuard {
pub count: usize,
}
#[derive(LintDiagnostic)]
#[diag(mir_build::irrefutable_let_patterns_let_else)]
#[note]
#[help]
pub struct IrrefutableLetPatternsLetElse {
pub count: usize,
}
#[derive(LintDiagnostic)]
#[diag(mir_build::irrefutable_let_patterns_while_let)]
#[note]
#[help]
pub struct IrrefutableLetPatternsWhileLet {
pub count: usize,
}

View File

@ -598,68 +598,24 @@ fn irrefutable_let_patterns(
count: usize,
span: Span,
) {
let span = match source {
LetSource::LetElse(span) => span,
_ => span,
};
macro_rules! emit_diag {
(
$lint:expr,
$source_name:expr,
$note_sufix:expr,
$help_sufix:expr
) => {{
let s = pluralize!(count);
let these = pluralize!("this", count);
tcx.struct_span_lint_hir(
IRREFUTABLE_LET_PATTERNS,
id,
span,
format!("irrefutable {} pattern{s}", $source_name),
|lint| {
lint.note(&format!(
"{these} pattern{s} will always match, so the {}",
$note_sufix
))
.help(concat!("consider ", $help_sufix))
},
)
($lint:tt) => {{
tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, id, span, $lint { count });
}};
}
match source {
LetSource::GenericLet => {
emit_diag!(lint, "`let`", "`let` is useless", "removing `let`");
}
LetSource::IfLet => {
emit_diag!(
lint,
"`if let`",
"`if let` is useless",
"replacing the `if let` with a `let`"
);
}
LetSource::IfLetGuard => {
emit_diag!(
lint,
"`if let` guard",
"guard is useless",
"removing the guard and adding a `let` inside the match arm"
);
}
LetSource::LetElse => {
emit_diag!(
lint,
"`let...else`",
"`else` clause is useless",
"removing the `else` clause"
);
}
LetSource::WhileLet => {
emit_diag!(
lint,
"`while let`",
"loop will never exit",
"instead using a `loop { ... }` with a `let` inside it"
);
}
};
LetSource::GenericLet => emit_diag!(IrrefutableLetPatternsGenericLet),
LetSource::IfLet => emit_diag!(IrrefutableLetPatternsIfLet),
LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard),
LetSource::LetElse(..) => emit_diag!(IrrefutableLetPatternsLetElse),
LetSource::WhileLet => emit_diag!(IrrefutableLetPatternsWhileLet),
}
}
fn is_let_irrefutable<'p, 'tcx>(