diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2024-11-07 18:34:40 +0000 | 
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2024-11-17 23:40:00 +0000 | 
| commit | a5b4d458a12218b2bbbcb42887d1fe1468f1986e (patch) | |
| tree | de10e97ff54c191c8c442423b6f0756632698e9b /compiler/rustc_mir_build/src | |
| parent | 6dc79f6133d24100cecbcb24e256b9f149d2b47a (diff) | |
| download | rust-a5b4d458a12218b2bbbcb42887d1fe1468f1986e.tar.gz rust-a5b4d458a12218b2bbbcb42887d1fe1468f1986e.zip | |
Point at const when intended binding fall-through pattern is a const
```
error[E0004]: non-exhaustive patterns: `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
  --> $DIR/intended-binding-pattern-is-const.rs:2:11
   |
LL |     match 1 {
   |           ^ patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
LL |         x => {}
   |         - this pattern doesn't introduce a new catch-all binding, but rather pattern matches against the value of constant `x`
   |
   = note: the matched value is of type `i32`
note: constant `x` defined here
  --> $DIR/intended-binding-pattern-is-const.rs:7:5
   |
LL |     const x: i32 = 4;
   |     ^^^^^^^^^^^^
help: if you meant to introduce a binding, use a different name
   |
LL |         x_var => {}
   |          ++++
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
   |
LL |         x => {}, i32::MIN..=3_i32 | 5_i32..=i32::MAX => todo!()
   |                ++++++++++++++++++++++++++++++++++++++++++++++++
```
Diffstat (limited to 'compiler/rustc_mir_build/src')
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 29 | 
1 files changed, 25 insertions, 4 deletions
| diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index a8830b346ae..edd51b521fa 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1116,13 +1116,13 @@ fn report_non_exhaustive_match<'p, 'tcx>( if ty.is_ptr_sized_integral() { if ty.inner() == cx.tcx.types.usize { err.note(format!( - "`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \ - exhaustively", + "`{ty}` does not have a fixed maximum value, so half-open ranges are \ + necessary to match exhaustively", )); } else if ty.inner() == cx.tcx.types.isize { err.note(format!( - "`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \ - exhaustively", + "`{ty}` does not have fixed minimum and maximum values, so half-open \ + ranges are necessary to match exhaustively", )); } } else if ty.inner() == cx.tcx.types.str_ { @@ -1143,6 +1143,27 @@ fn report_non_exhaustive_match<'p, 'tcx>( } } + for &arm in arms { + let arm = &thir.arms[arm]; + if let PatKind::Constant { opt_def: Some(def_id), .. } = arm.pattern.kind { + let const_name = cx.tcx.item_name(def_id); + err.span_label( + arm.pattern.span, + format!( + "this pattern doesn't introduce a new catch-all binding, but rather pattern \ + matches against the value of constant `{const_name}`", + ), + ); + err.span_note(cx.tcx.def_span(def_id), format!("constant `{const_name}` defined here")); + err.span_suggestion_verbose( + arm.pattern.span.shrink_to_hi(), + "if you meant to introduce a binding, use a different name", + "_var".to_string(), + Applicability::MaybeIncorrect, + ); + } + } + // Whether we suggest the actual missing patterns or `_`. let suggest_the_witnesses = witnesses.len() < 4; let suggested_arm = if suggest_the_witnesses { | 
