Skip to content

Commit

Permalink
When finding a match expr with multiple arms that requires more, sugg…
Browse files Browse the repository at this point in the history
…est it

Given

```rust
match Some(42) {
    Some(0) => {}
    Some(1) => {}
}
```

suggest

```rust
match Some(42) {
    Some(0) => {}
    Some(1) => {}
    None | Some(_) => todo!(),
}
```
  • Loading branch information
estebank committed Mar 8, 2022
1 parent 2383858 commit 084ca79
Show file tree
Hide file tree
Showing 28 changed files with 263 additions and 50 deletions.
15 changes: 15 additions & 0 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Expand Up @@ -604,6 +604,21 @@ fn non_exhaustive_match<'p, 'tcx>(
format!("{}{}{} => todo!()", comma, pre_indentation, pattern),
));
}
[.., prev, last] if prev.span.ctxt() == last.span.ctxt() => {
if let Ok(snippet) = sm.span_to_snippet(prev.span.between(last.span)) {
let comma =
if matches!(last.body.kind, hir::ExprKind::Block(..)) { "" } else { "," };
suggestion = Some((
last.span.shrink_to_hi(),
format!(
"{}{}{} => todo!()",
comma,
snippet.strip_prefix(",").unwrap_or(&snippet),
pattern
),
));
}
}
_ => {}
}

Expand Down
Expand Up @@ -37,7 +37,10 @@ LL | let _e = || { match e2 { E2::A => (), E2::B => () } };
| ^^ pattern `_` not covered
|
= note: the matched value is of type `E2`, which is marked as non-exhaustive
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL | let _e = || { match e2 { E2::A => (), E2::B => (), _ => todo!() } };
| ++++++++++++++

error[E0505]: cannot move out of `e3` because it is borrowed
--> $DIR/non-exhaustive-match.rs:46:22
Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/match/match_non_exhaustive.stderr
Expand Up @@ -37,7 +37,10 @@ LL | match e2 { E2::A => (), E2::B => () };
| ^^ pattern `_` not covered
|
= note: the matched value is of type `E2`, which is marked as non-exhaustive
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL | match e2 { E2::A => (), E2::B => (), _ => todo!() };
| ++++++++++++++

error: aborting due to 3 previous errors

Expand Down
18 changes: 15 additions & 3 deletions src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr
Expand Up @@ -5,7 +5,11 @@ LL | match Foo::A {
| ^^^^^^ pattern `_` not covered
|
= note: the matched value is of type `Foo`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ Foo::B => {}
LL + _ => todo!()
|

error[E0004]: non-exhaustive patterns: `B` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:14:11
Expand All @@ -19,7 +23,11 @@ LL | B,
| - not covered
|
= note: the matched value is of type `Foo`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ Foo::C => {}
LL + B => todo!()
|

error[E0004]: non-exhaustive patterns: `B` and `_` not covered
--> $DIR/doc-hidden-non-exhaustive.rs:20:11
Expand Down Expand Up @@ -51,7 +59,11 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
| ---- not covered
|
= note: the matched value is of type `Option<Foo>`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ Some(Foo::A) => {}
LL + Some(B) | Some(_) => todo!()
|

error: aborting due to 4 previous errors

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/guards.stderr
Expand Up @@ -5,7 +5,11 @@ LL | match 0u8 {
| ^^^ pattern `128_u8..=u8::MAX` not covered
|
= note: the matched value is of type `u8`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ 128 ..= 255 if true => {}
LL + 128_u8..=u8::MAX => todo!()
|

error: aborting due to previous error

Expand Down
Expand Up @@ -96,7 +96,11 @@ LL | match 0i8 {
| ^^^ pattern `0_i8` not covered
|
= note: the matched value is of type `i8`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ 1 ..= i8::MAX => {}
LL + 0_i8 => todo!()
|

error[E0004]: non-exhaustive patterns: `u128::MAX` not covered
--> $DIR/exhaustiveness.rs:59:8
Expand Down Expand Up @@ -144,7 +148,11 @@ LL | match (0u8, true) {
| ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered
|
= note: the matched value is of type `(u8, bool)`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ (0 ..= 255, true) => {}
LL + (126_u8..=127_u8, false) => todo!()
|

error: aborting due to 12 previous errors

Expand Down
Expand Up @@ -153,7 +153,11 @@ LL | match 0isize {
= note: the matched value is of type `isize`
= note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively
= help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ 1 ..= isize::MAX => {}
LL + _ => todo!()
|

error[E0004]: non-exhaustive patterns: type `usize` is non-empty
--> $DIR/pointer-sized-int.rs:48:11
Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/issue-15129.stderr
Expand Up @@ -5,7 +5,11 @@ LL | match (T::T1(()), V::V2(true)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `(T1(()), V2(_))` and `(T2(()), V1(_))` not covered
|
= note: the matched value is of type `(T, V)`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ (T::T2(()), V::V2(b)) => (),
LL ~ (T1(()), V2(_)) | (T2(()), V1(_)) => todo!(),
|

error: aborting due to previous error

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/issue-2111.stderr
Expand Up @@ -5,7 +5,11 @@ LL | match (a, b) {
| ^^^^^^ patterns `(None, None)` and `(Some(_), Some(_))` not covered
|
= note: the matched value is of type `(Option<usize>, Option<usize>)`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ (Some(_), None) | (None, Some(_)) => {}
LL + (None, None) | (Some(_), Some(_)) => todo!()
|

error: aborting due to previous error

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/issue-30240.stderr
Expand Up @@ -18,7 +18,11 @@ LL | match "world" {
| ^^^^^^^ pattern `&_` not covered
|
= note: the matched value is of type `&str`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ "hello" => {}
LL + &_ => todo!()
|

error: aborting due to 2 previous errors

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/issue-35609.stderr
Expand Up @@ -102,7 +102,11 @@ LL | match Some(A) {
| ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered
|
= note: the matched value is of type `Option<Enum>`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ None => (),
LL + _ => todo!()
|

error: aborting due to 8 previous errors

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/issue-39362.stderr
Expand Up @@ -10,7 +10,11 @@ LL | match f {
| ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered
|
= note: the matched value is of type `Foo`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ Foo::Bar { bar: Bar::B, .. } => (),
LL ~ _ => todo!(),
|

error: aborting due to previous error

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/issue-4321.stderr
Expand Up @@ -5,7 +5,11 @@ LL | println!("foo {:}", match tup {
| ^^^ pattern `(true, false)` not covered
|
= note: the matched value is of type `(bool, bool)`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ (true, true) => "baz",
LL + (true, false) => todo!()
|

error: aborting due to previous error

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/issue-56379.stderr
Expand Up @@ -15,7 +15,11 @@ LL | match Foo::A(true) {
| ^^^^^^^^^^^^ patterns `A(false)`, `B(false)` and `C(false)` not covered
|
= note: the matched value is of type `Foo`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ Foo::C(true) => {}
LL + A(false) | B(false) | C(false) => todo!()
|

error: aborting due to previous error

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/issue-72377.stderr
Expand Up @@ -5,7 +5,11 @@ LL | match (x, y) {
| ^^^^^^ patterns `(A, Some(A))`, `(A, Some(B))`, `(B, Some(B))` and 2 more not covered
|
= note: the matched value is of type `(X, Option<X>)`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ (X::A, Some(X::C)) | (X::C, Some(X::A)) => false,
LL ~ _ => todo!(),
|

error: aborting due to previous error

Expand Down
18 changes: 15 additions & 3 deletions src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
Expand Up @@ -5,7 +5,11 @@ LL | match (true, false) {
| ^^^^^^^^^^^^^ pattern `(true, false)` not covered
|
= note: the matched value is of type `(bool, bool)`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ (false, true) => (),
LL + (true, false) => todo!()
|

error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
--> $DIR/match-arm-statics-2.rs:29:11
Expand All @@ -22,7 +26,11 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
| not covered
|
= note: the matched value is of type `Option<Option<Direction>>`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ None => (),
LL + Some(Some(West)) => todo!()
|

error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered
--> $DIR/match-arm-statics-2.rs:48:11
Expand All @@ -37,7 +45,11 @@ LL | match (Foo { bar: Some(North), baz: NewBool(true) }) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered
|
= note: the matched value is of type `Foo`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ Foo { bar: Some(EAST), .. } => (),
LL + Foo { bar: Some(North), baz: NewBool(true) } => todo!()
|

error: aborting due to 3 previous errors

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/match-privately-empty.stderr
Expand Up @@ -10,7 +10,11 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
| ---- not covered
|
= note: the matched value is of type `Option<Private>`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ }) => {}
LL + Some(Private { misc: true, .. }) => todo!()
|

error: aborting due to previous error

Expand Down
6 changes: 5 additions & 1 deletion src/test/ui/pattern/usefulness/match-slice-patterns.stderr
Expand Up @@ -5,7 +5,11 @@ LL | match list {
| ^^^^ pattern `&[_, Some(_), .., None, _]` not covered
|
= note: the matched value is of type `&[Option<()>]`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ &[.., Some(_), _] => {}
LL ~ &[_, Some(_), .., None, _] => todo!(),
|

error: aborting due to previous error

Expand Down
12 changes: 10 additions & 2 deletions src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr
Expand Up @@ -5,7 +5,11 @@ LL | match (l1, l2) {
| ^^^^^^^^ pattern `(Some(&[]), Err(_))` not covered
|
= note: the matched value is of type `(Option<&[T]>, Result<&[T], ()>)`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ (None, Ok(&[_, _, ..])) => "None, Ok(at least two elements)",
LL + (Some(&[]), Err(_)) => todo!()
|

error[E0004]: non-exhaustive patterns: `A(C)` not covered
--> $DIR/non-exhaustive-match-nested.rs:15:11
Expand All @@ -20,7 +24,11 @@ LL | match x {
| ^ pattern `A(C)` not covered
|
= note: the matched value is of type `T`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ T::B => { panic!("goodbye"); }
LL + A(C) => todo!()
|

error: aborting due to 2 previous errors

Expand Down
18 changes: 15 additions & 3 deletions src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
Expand Up @@ -67,7 +67,11 @@ LL | match (T::A, T::A) {
| ^^^^^^^^^^^^ patterns `(A, A)` and `(B, B)` not covered
|
= note: the matched value is of type `(T, T)`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ (T::B, T::A) => {}
LL + (A, A) | (B, B) => todo!()
|

error[E0004]: non-exhaustive patterns: `B` not covered
--> $DIR/non-exhaustive-match.rs:22:11
Expand Down Expand Up @@ -95,7 +99,11 @@ LL | match *vec {
| ^^^^ pattern `[]` not covered
|
= note: the matched value is of type `[Option<isize>]`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ [None] => {}
LL + [] => todo!()
|

error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
--> $DIR/non-exhaustive-match.rs:46:11
Expand All @@ -104,7 +112,11 @@ LL | match *vec {
| ^^^^ pattern `[_, _, _, _, ..]` not covered
|
= note: the matched value is of type `[f32]`
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
LL ~ [] => (),
LL + [_, _, _, _, ..] => todo!()
|

error: aborting due to 8 previous errors

Expand Down

0 comments on commit 084ca79

Please sign in to comment.