Skip to content

Commit d873ee6

Browse files
committed
Migrate leading/trailing irrefutable let pattern diagnostics
1 parent ae2e7af commit d873ee6

File tree

3 files changed

+52
-21
lines changed

3 files changed

+52
-21
lines changed

compiler/rustc_error_messages/locales/en-US/mir_build.ftl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,29 @@ mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper =
207207
.teach_note = When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range.
208208
209209
mir_build_lower_range_bound_must_be_less_than_upper = lower range bound must be less than upper
210+
211+
mir_build_leading_irrefutable_let_patterns = leading irrefutable {$count ->
212+
[one] pattern
213+
*[other] patterns
214+
} in let chain
215+
.note = {$count ->
216+
[one] this pattern
217+
*[other] these patterns
218+
} will always match
219+
.help = consider moving {$count ->
220+
[one] it
221+
*[other] them
222+
} outside of the construct
223+
224+
mir_build_trailing_irrefutable_let_patterns = trailing irrefutable {$count ->
225+
[one] pattern
226+
*[other] patterns
227+
} in let chain
228+
.note = {$count ->
229+
[one] this pattern
230+
*[other] these patterns
231+
} will always match
232+
.help = consider moving {$count ->
233+
[one] it
234+
*[other] them
235+
} into the body

compiler/rustc_mir_build/src/errors.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,19 @@ pub struct LowerRangeBoundMustBeLessThanUpper {
497497
#[primary_span]
498498
pub span: Span,
499499
}
500+
501+
#[derive(LintDiagnostic)]
502+
#[diag(mir_build::leading_irrefutable_let_patterns)]
503+
#[note]
504+
#[help]
505+
pub struct LeadingIrrefutableLetPatterns {
506+
pub count: usize,
507+
}
508+
509+
#[derive(LintDiagnostic)]
510+
#[diag(mir_build::trailing_irrefutable_let_patterns)]
511+
#[note]
512+
#[help]
513+
pub struct TrailingIrrefutableLetPatterns {
514+
pub count: usize,
515+
}

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -336,25 +336,6 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
336336
);
337337
return true;
338338
}
339-
let lint_affix = |affix: &[Option<(Span, bool)>], kind, suggestion| {
340-
let span_start = affix[0].unwrap().0;
341-
let span_end = affix.last().unwrap().unwrap().0;
342-
let span = span_start.to(span_end);
343-
let cnt = affix.len();
344-
cx.tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, top, span, |lint| {
345-
let s = pluralize!(cnt);
346-
let mut diag = lint.build(&format!("{kind} irrefutable pattern{s} in let chain"));
347-
diag.note(&format!(
348-
"{these} pattern{s} will always match",
349-
these = pluralize!("this", cnt),
350-
));
351-
diag.help(&format!(
352-
"consider moving {} {suggestion}",
353-
if cnt > 1 { "them" } else { "it" }
354-
));
355-
diag.emit()
356-
});
357-
};
358339
if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 {
359340
// The chain has a non-zero prefix of irrefutable `let` statements.
360341

@@ -364,13 +345,21 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
364345
if !matches!(let_source, LetSource::WhileLet) {
365346
// Emit the lint
366347
let prefix = &chain_refutabilities[..until];
367-
lint_affix(prefix, "leading", "outside of the construct");
348+
let span_start = prefix[0].unwrap().0;
349+
let span_end = prefix.last().unwrap().unwrap().0;
350+
let span = span_start.to(span_end);
351+
let count = prefix.len();
352+
cx.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, top, span, LeadingIrrefutableLetPatterns { count });
368353
}
369354
}
370355
if let Some(from) = chain_refutabilities.iter().rposition(|r| !matches!(*r, Some((_, false)))) && from != (chain_refutabilities.len() - 1) {
371356
// The chain has a non-empty suffix of irrefutable `let` statements
372357
let suffix = &chain_refutabilities[from + 1..];
373-
lint_affix(suffix, "trailing", "into the body");
358+
let span_start = suffix[0].unwrap().0;
359+
let span_end = suffix.last().unwrap().unwrap().0;
360+
let span = span_start.to(span_end);
361+
let count = suffix.len();
362+
cx.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, top, span, TrailingIrrefutableLetPatterns { count });
374363
}
375364
true
376365
}

0 commit comments

Comments
 (0)