Skip to content

Commit 42a8f37

Browse files
lzcuntmejrs
authored and
mejrs
committed
Migrate leading/trailing irrefutable let pattern diagnostics
1 parent 5c64edf commit 42a8f37

File tree

3 files changed

+52
-25
lines changed

3 files changed

+52
-25
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 & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -339,29 +339,6 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
339339
);
340340
return true;
341341
}
342-
let lint_affix = |affix: &[Option<(Span, bool)>], kind, suggestion| {
343-
let span_start = affix[0].unwrap().0;
344-
let span_end = affix.last().unwrap().unwrap().0;
345-
let span = span_start.to(span_end);
346-
let cnt = affix.len();
347-
let s = pluralize!(cnt);
348-
cx.tcx.struct_span_lint_hir(
349-
IRREFUTABLE_LET_PATTERNS,
350-
top,
351-
span,
352-
format!("{kind} irrefutable pattern{s} in let chain"),
353-
|lint| {
354-
lint.note(format!(
355-
"{these} pattern{s} will always match",
356-
these = pluralize!("this", cnt),
357-
))
358-
.help(format!(
359-
"consider moving {} {suggestion}",
360-
if cnt > 1 { "them" } else { "it" }
361-
))
362-
},
363-
);
364-
};
365342
if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 {
366343
// The chain has a non-zero prefix of irrefutable `let` statements.
367344

@@ -375,13 +352,21 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
375352
if !matches!(let_source, LetSource::WhileLet | LetSource::IfLetGuard) {
376353
// Emit the lint
377354
let prefix = &chain_refutabilities[..until];
378-
lint_affix(prefix, "leading", "outside of the construct");
355+
let span_start = prefix[0].unwrap().0;
356+
let span_end = prefix.last().unwrap().unwrap().0;
357+
let span = span_start.to(span_end);
358+
let count = prefix.len();
359+
cx.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, top, span, LeadingIrrefutableLetPatterns { count });
379360
}
380361
}
381362
if let Some(from) = chain_refutabilities.iter().rposition(|r| !matches!(*r, Some((_, false)))) && from != (chain_refutabilities.len() - 1) {
382363
// The chain has a non-empty suffix of irrefutable `let` statements
383364
let suffix = &chain_refutabilities[from + 1..];
384-
lint_affix(suffix, "trailing", "into the body");
365+
let span_start = suffix[0].unwrap().0;
366+
let span_end = suffix.last().unwrap().unwrap().0;
367+
let span = span_start.to(span_end);
368+
let count = suffix.len();
369+
cx.tcx.emit_spanned_lint(IRREFUTABLE_LET_PATTERNS, top, span, TrailingIrrefutableLetPatterns { count });
385370
}
386371
true
387372
}

0 commit comments

Comments
 (0)