mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
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!() | ++++++++++++++++++++++++++++++++++++++++++++++++ ```
This commit is contained in:
parent
6dc79f6133
commit
a5b4d458a1
@ -1116,13 +1116,13 @@ fn report_non_exhaustive_match<'p, 'tcx>(
|
|||||||
if ty.is_ptr_sized_integral() {
|
if ty.is_ptr_sized_integral() {
|
||||||
if ty.inner() == cx.tcx.types.usize {
|
if ty.inner() == cx.tcx.types.usize {
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
"`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \
|
"`{ty}` does not have a fixed maximum value, so half-open ranges are \
|
||||||
exhaustively",
|
necessary to match exhaustively",
|
||||||
));
|
));
|
||||||
} else if ty.inner() == cx.tcx.types.isize {
|
} else if ty.inner() == cx.tcx.types.isize {
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
"`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \
|
"`{ty}` does not have fixed minimum and maximum values, so half-open \
|
||||||
exhaustively",
|
ranges are necessary to match exhaustively",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else if ty.inner() == cx.tcx.types.str_ {
|
} 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 `_`.
|
// Whether we suggest the actual missing patterns or `_`.
|
||||||
let suggest_the_witnesses = witnesses.len() < 4;
|
let suggest_the_witnesses = witnesses.len() < 4;
|
||||||
let suggested_arm = if suggest_the_witnesses {
|
let suggested_arm = if suggest_the_witnesses {
|
||||||
|
10
tests/ui/match/intended-binding-pattern-is-const.rs
Normal file
10
tests/ui/match/intended-binding-pattern-is-const.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fn main() {
|
||||||
|
match 1 { //~ ERROR non-exhaustive patterns
|
||||||
|
//~^ patterns `i32::MIN..=3_i32` and `5_i32..=i32::MAX` not covered
|
||||||
|
//~| the matched value is of type `i32`
|
||||||
|
x => {} //~ this pattern doesn't introduce a new catch-all binding
|
||||||
|
//~^ HELP ensure that all possible cases are being handled
|
||||||
|
//~| HELP if you meant to introduce a binding, use a different name
|
||||||
|
}
|
||||||
|
const x: i32 = 4; //~ NOTE constant `x` defined here
|
||||||
|
}
|
27
tests/ui/match/intended-binding-pattern-is-const.stderr
Normal file
27
tests/ui/match/intended-binding-pattern-is-const.stderr
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
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:9: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!()
|
||||||
|
| ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0004`.
|
Loading…
Reference in New Issue
Block a user