]> git.lizzy.rs Git - rust.git/commitdiff
Suggest `if let`/`let_else` for refutable pat in `let`
authorEsteban Kuber <esteban@kuber.com.ar>
Tue, 8 Mar 2022 05:54:38 +0000 (05:54 +0000)
committerEsteban Kuber <esteban@kuber.com.ar>
Tue, 8 Mar 2022 16:32:08 +0000 (16:32 +0000)
15 files changed:
compiler/rustc_mir_build/src/thir/pattern/check_match.rs
src/test/ui/consts/const-match-check.eval1.stderr
src/test/ui/consts/const-match-check.eval2.stderr
src/test/ui/consts/const-match-check.matchck.stderr
src/test/ui/empty/empty-never-array.stderr
src/test/ui/error-codes/E0005.stderr
src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
src/test/ui/pattern/usefulness/issue-31561.stderr
src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr
src/test/ui/pattern/usefulness/refutable-pattern-errors.stderr
src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
src/test/ui/uninhabited/uninhabited-irrefutable.rs
src/test/ui/uninhabited/uninhabited-irrefutable.stderr
src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr

index b80d2e52ee709cabe32710b81b38ecbad2294d33..dae313da8d993c6cfd161bd3bfd35f7a7c8094ab 100644 (file)
@@ -7,7 +7,8 @@
 use rustc_arena::TypedArena;
 use rustc_ast::Mutability;
 use rustc_errors::{
-    error_code, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
+    error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder,
+    ErrorGuaranteed,
 };
 use rustc_hir as hir;
 use rustc_hir::def::*;
@@ -20,7 +21,7 @@
 };
 use rustc_session::Session;
 use rustc_span::source_map::Spanned;
-use rustc_span::{DesugaringKind, ExpnKind, MultiSpan, Span};
+use rustc_span::{BytePos, DesugaringKind, ExpnKind, MultiSpan, Span};
 
 crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
     let body_id = match def_id.as_local() {
@@ -241,6 +242,9 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
         }
 
         let joined_patterns = joined_uncovered_patterns(&cx, &witnesses);
+
+        let mut bindings = vec![];
+
         let mut err = struct_span_err!(
             self.tcx.sess,
             pat.span,
@@ -257,6 +261,16 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
                 false
             }
             _ => {
+                pat.walk(&mut |pat: &hir::Pat<'_>| {
+                    match pat.kind {
+                        hir::PatKind::Binding(_, _, ident, _) => {
+                            bindings.push(ident);
+                        }
+                        _ => {}
+                    }
+                    true
+                });
+
                 err.span_label(pat.span, pattern_not_covered_label(&witnesses, &joined_patterns));
                 true
             }
@@ -267,13 +281,71 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
                 "`let` bindings require an \"irrefutable pattern\", like a `struct` or \
                  an `enum` with only one variant",
             );
-            if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
-                err.span_suggestion(
-                    span,
-                    "you might want to use `if let` to ignore the variant that isn't matched",
-                    format!("if {} {{ /* */ }}", &snippet[..snippet.len() - 1]),
+            if self.tcx.sess.source_map().span_to_snippet(span).is_ok() {
+                let semi_span = span.shrink_to_hi().with_lo(span.hi() - BytePos(1));
+                let start_span = span.shrink_to_lo();
+                let end_span = semi_span.shrink_to_lo();
+                err.multipart_suggestion(
+                    &format!(
+                        "you might want to use `if let` to ignore the variant{} that {} matched",
+                        pluralize!(witnesses.len()),
+                        match witnesses.len() {
+                            1 => "isn't",
+                            _ => "aren't",
+                        },
+                    ),
+                    vec![
+                        match &bindings[..] {
+                            [] => (start_span, "if ".to_string()),
+                            [binding] => (start_span, format!("let {} = if ", binding)),
+                            bindings => (
+                                start_span,
+                                format!(
+                                    "let ({}) = if ",
+                                    bindings
+                                        .iter()
+                                        .map(|ident| ident.to_string())
+                                        .collect::<Vec<_>>()
+                                        .join(", ")
+                                ),
+                            ),
+                        },
+                        match &bindings[..] {
+                            [] => (semi_span, " { todo!() }".to_string()),
+                            [binding] => {
+                                (end_span, format!(" {{ {} }} else {{ todo!() }}", binding))
+                            }
+                            bindings => (
+                                end_span,
+                                format!(
+                                    " {{ ({}) }} else {{ todo!() }}",
+                                    bindings
+                                        .iter()
+                                        .map(|ident| ident.to_string())
+                                        .collect::<Vec<_>>()
+                                        .join(", ")
+                                ),
+                            ),
+                        },
+                    ],
                     Applicability::HasPlaceholders,
                 );
+                if cx.tcx.sess.is_nightly_build() {
+                    err.span_suggestion_verbose(
+                        semi_span.shrink_to_lo(),
+                        &format!(
+                            "alternatively, on nightly, you might want to use \
+                             `#![feature(let_else)]` to handle the variant{} that {} matched",
+                            pluralize!(witnesses.len()),
+                            match witnesses.len() {
+                                1 => "isn't",
+                                _ => "aren't",
+                            },
+                        ),
+                        " else { todo!() }".to_string(),
+                        Applicability::HasPlaceholders,
+                    );
+                }
             }
             err.note(
                 "for more information, visit \
index 4141cc4ab1a48d90a0ebae26159c61ec0f7ad1ee..08ee800f138d2478f4f041d8f4f203d34ae2c43c 100644 (file)
@@ -7,10 +7,14 @@ LL |     A = { let 0 = 0; 0 },
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL |     A = { if let 0 = 0 { /* */ } 0 },
-   |           ~~~~~~~~~~~~~~~~~~~~~~
+LL |     A = { if let 0 = 0 { todo!() } 0 },
+   |           ++           ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
+   |
+LL |     A = { let 0 = 0 else { todo!() }; 0 },
+   |                     ++++++++++++++++
 
 error: aborting due to previous error
 
index af86ba0cc82f8684a440e85df82d0f1a20ca296e..579cb7e780007faadd230ba5bee1bd2e3273d02c 100644 (file)
@@ -7,10 +7,14 @@ LL |     let x: [i32; { let 0 = 0; 0 }] = [];
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL |     let x: [i32; { if let 0 = 0 { /* */ } 0 }] = [];
-   |                    ~~~~~~~~~~~~~~~~~~~~~~
+LL |     let x: [i32; { if let 0 = 0 { todo!() } 0 }] = [];
+   |                    ++           ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
+   |
+LL |     let x: [i32; { let 0 = 0 else { todo!() }; 0 }] = [];
+   |                              ++++++++++++++++
 
 error: aborting due to previous error
 
index f71490eba613541be69dc6956a977315fc1dac49..f89bbc0d42234447a3d195300f54c8165cf26679 100644 (file)
@@ -7,10 +7,14 @@ LL | const X: i32 = { let 0 = 0; 0 };
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL | const X: i32 = { if let 0 = 0 { /* */ } 0 };
-   |                  ~~~~~~~~~~~~~~~~~~~~~~
+LL | const X: i32 = { if let 0 = 0 { todo!() } 0 };
+   |                  ++           ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
+   |
+LL | const X: i32 = { let 0 = 0 else { todo!() }; 0 };
+   |                            ++++++++++++++++
 
 error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
   --> $DIR/const-match-check.rs:8:23
@@ -21,10 +25,14 @@ LL | static Y: i32 = { let 0 = 0; 0 };
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
+   |
+LL | static Y: i32 = { if let 0 = 0 { todo!() } 0 };
+   |                   ++           ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
    |
-LL | static Y: i32 = { if let 0 = 0 { /* */ } 0 };
-   |                   ~~~~~~~~~~~~~~~~~~~~~~
+LL | static Y: i32 = { let 0 = 0 else { todo!() }; 0 };
+   |                             ++++++++++++++++
 
 error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
   --> $DIR/const-match-check.rs:13:26
@@ -35,10 +43,14 @@ LL |     const X: i32 = { let 0 = 0; 0 };
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL |     const X: i32 = { if let 0 = 0 { /* */ } 0 };
-   |                      ~~~~~~~~~~~~~~~~~~~~~~
+LL |     const X: i32 = { if let 0 = 0 { todo!() } 0 };
+   |                      ++           ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
+   |
+LL |     const X: i32 = { let 0 = 0 else { todo!() }; 0 };
+   |                                ++++++++++++++++
 
 error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
   --> $DIR/const-match-check.rs:19:26
@@ -49,10 +61,14 @@ LL |     const X: i32 = { let 0 = 0; 0 };
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
+   |
+LL |     const X: i32 = { if let 0 = 0 { todo!() } 0 };
+   |                      ++           ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
    |
-LL |     const X: i32 = { if let 0 = 0 { /* */ } 0 };
-   |                      ~~~~~~~~~~~~~~~~~~~~~~
+LL |     const X: i32 = { let 0 = 0 else { todo!() }; 0 };
+   |                                ++++++++++++++++
 
 error: aborting due to 4 previous errors
 
index 8dd0f377533ce8c0dc0ce1a22e1252c4daf38da2..909aa73a74a38fb2a9b8313de32527f95ad9c9ce 100644 (file)
@@ -16,8 +16,12 @@ LL |     T(T, [!; 0]),
    = note: the matched value is of type `Helper<T, U>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
-LL |     if let Helper::U(u) = Helper::T(t, []) { /* */ }
+LL |     let u = if let Helper::U(u) = Helper::T(t, []) { u } else { todo!() };
+   |     ++++++++++                                     ++++++++++++++++++++++
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
    |
+LL |     let Helper::U(u) = Helper::T(t, []) else { todo!() };
+   |                                         ++++++++++++++++
 
 error: aborting due to previous error
 
index 208c625a53e959c7df055d372bc5c1324b2249f3..55b1112b5f8ecb4e0f1993894fb6241c3f1f65e6 100644 (file)
@@ -22,8 +22,12 @@ LL | | }
    = note: the matched value is of type `Option<i32>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
-LL |     if let Some(y) = x { /* */ }
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     let y = if let Some(y) = x { y } else { todo!() };
+   |     ++++++++++                 ++++++++++++++++++++++
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+   |
+LL |     let Some(y) = x else { todo!() };
+   |                     ++++++++++++++++
 
 error: aborting due to previous error
 
index c2ffda6bb72d24e97dae7ce25fdcdfe0637b21d3..21180f31bbd26a11a59631f1f1966072ee34cbab 100644 (file)
@@ -21,8 +21,12 @@ LL | | }
    = note: the matched value is of type `Result<u32, !>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
-LL |     if let Ok(_x) = foo() { /* */ }
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     let _x = if let Ok(_x) = foo() { _x } else { todo!() };
+   |     +++++++++++                    +++++++++++++++++++++++
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+   |
+LL |     let Ok(_x) = foo() else { todo!() };
+   |                        ++++++++++++++++
 
 error: aborting due to previous error
 
index 37a35700b36d5731ebc544d4e1de7a2ad5c43263..aa1aa4434c3fa4e84c2288fd4d1025de87592ce3 100644 (file)
@@ -7,10 +7,14 @@ LL |     let (0 | (1 | 2)) = 0;
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL |     if let (0 | (1 | 2)) = 0 { /* */ }
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     if let (0 | (1 | 2)) = 0 { todo!() }
+   |     ++                       ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
+   |
+LL |     let (0 | (1 | 2)) = 0 else { todo!() };
+   |                           ++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
   --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:3:11
index dffcfc016072f28d78c769ea47d0292ce2601ae6..9da6b5eeead235a575107bbde68c86eda7eb0204 100644 (file)
@@ -17,10 +17,14 @@ LL |     Bar,
 LL |     Baz
    |     ^^^ not covered
    = note: the matched value is of type `Thing`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL |     if let Thing::Foo(y) = Thing::Foo(1) { /* */ }
+LL |     let y = if let Thing::Foo(y) = Thing::Foo(1) { y } else { todo!() };
+   |     ++++++++++                                   ++++++++++++++++++++++
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
    |
+LL |     let Thing::Foo(y) = Thing::Foo(1) else { todo!() };
+   |                                       ++++++++++++++++
 
 error: aborting due to previous error
 
index 8f5adccea806db36ba27570cf92d19421e6e8502..f7dc070f802489986a765057c9d49784f750a7be 100644 (file)
@@ -42,10 +42,14 @@ LL |     B,
 LL |     C
    |     ^ not covered
    = note: the matched value is of type `E`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
+   |
+LL |     if let E::A = e { todo!() }
+   |     ++              ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
    |
-LL |     if let E::A = e { /* */ }
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     let E::A = e else { todo!() };
+   |                  ++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `&B` and `&C` not covered
   --> $DIR/non-exhaustive-defined-here.rs:52:11
@@ -91,10 +95,14 @@ LL |     B,
 LL |     C
    |     ^ not covered
    = note: the matched value is of type `&E`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL |     if let E::A = e { /* */ }
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     if let E::A = e { todo!() }
+   |     ++              ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
+   |
+LL |     let E::A = e else { todo!() };
+   |                  ++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered
   --> $DIR/non-exhaustive-defined-here.rs:66:11
@@ -140,10 +148,14 @@ LL |     B,
 LL |     C
    |     ^ not covered
    = note: the matched value is of type `&&mut &E`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL |     if let E::A = e { /* */ }
+LL |     if let E::A = e { todo!() }
+   |     ++              ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
    |
+LL |     let E::A = e else { todo!() };
+   |                  ++++++++++++++++
 
 error[E0004]: non-exhaustive patterns: `None` not covered
   --> $DIR/non-exhaustive-defined-here.rs:92:11
@@ -185,8 +197,12 @@ LL |     None,
    = note: the matched value is of type `Opt`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
-LL |     if let Opt::Some(ref _x) = e { /* */ }
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     let _x = if let Opt::Some(ref _x) = e { _x } else { todo!() };
+   |     +++++++++++                           +++++++++++++++++++++++
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+   |
+LL |     let Opt::Some(ref _x) = e else { todo!() };
+   |                               ++++++++++++++++
 
 error: aborting due to 8 previous errors
 
index 74ec646e31cca27b5507217ca02b197c51fc2d0d..e3ffc092327acc8bf0dfe47975010cde9ec8d5a4 100644 (file)
@@ -15,10 +15,14 @@ LL |     let (1, (Some(1), 2..=3)) = (1, (None, 2));
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `(i32, (Option<i32>, i32))`
-help: you might want to use `if let` to ignore the variant that isn't matched
+help: you might want to use `if let` to ignore the variants that aren't matched
    |
-LL |     if let (1, (Some(1), 2..=3)) = (1, (None, 2)) { /* */ }
+LL |     if let (1, (Some(1), 2..=3)) = (1, (None, 2)) { todo!() }
+   |     ++                                            ~~~~~~~~~~~
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variants that aren't matched
    |
+LL |     let (1, (Some(1), 2..=3)) = (1, (None, 2)) else { todo!() };
+   |                                                ++++++++++++++++
 
 error: aborting due to 2 previous errors
 
index ded3cf3ad1d44ab24ed3bd39afea4f634b965b7d..a9159562d9d512858354816138493869f75349e5 100644 (file)
@@ -21,8 +21,12 @@ LL | | }
    = note: the matched value is of type `Result<u32, &R>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
-LL |     if let Ok(x) = res { /* */ }
+LL |     let x = if let Ok(x) = res { x } else { todo!() };
+   |     ++++++++++                 ++++++++++++++++++++++
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
    |
+LL |     let Ok(x) = res else { todo!() };
+   |                     ++++++++++++++++
 
 error: aborting due to previous error
 
index 48cd92719b49ab51198e56727c30abd90b39ed79..661b5486adc122ca9cfe4f19d17ee0625f654304 100644 (file)
@@ -19,10 +19,10 @@ enum Foo {
     A(foo::SecretlyEmpty),
     B(foo::NotSoSecretlyEmpty),
     C(NotSoSecretlyEmpty),
-    D(u32),
+    D(u32, u32),
 }
 
 fn main() {
-    let x: Foo = Foo::D(123);
-    let Foo::D(_y) = x; //~ ERROR refutable pattern in local binding: `A(_)` not covered
+    let x: Foo = Foo::D(123, 456);
+    let Foo::D(_y, _z) = x; //~ ERROR refutable pattern in local binding: `A(_)` not covered
 }
index ad19c34a40a110237acf2eba71de2aa30ea23c74..c571e17a7b372516a801b64476dec81bfae86fde 100644 (file)
@@ -1,8 +1,8 @@
 error[E0005]: refutable pattern in local binding: `A(_)` not covered
   --> $DIR/uninhabited-irrefutable.rs:27:9
    |
-LL |     let Foo::D(_y) = x;
-   |         ^^^^^^^^^^ pattern `A(_)` not covered
+LL |     let Foo::D(_y, _z) = x;
+   |         ^^^^^^^^^^^^^^ pattern `A(_)` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
@@ -16,8 +16,12 @@ LL |     A(foo::SecretlyEmpty),
    = note: the matched value is of type `Foo`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
-LL |     if let Foo::D(_y) = x { /* */ }
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL |     let (_y, _z) = if let Foo::D(_y, _z) = x { (_y, _z) } else { todo!() };
+   |     +++++++++++++++++                        +++++++++++++++++++++++++++++
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
+   |
+LL |     let Foo::D(_y, _z) = x else { todo!() };
+   |                            ++++++++++++++++
 
 error: aborting due to previous error
 
index d90075d82f47b37defdc1e6a6d67b240ece67c86..74216d265d03416e218903443c3a6c5d46a9ef0c 100644 (file)
@@ -132,8 +132,12 @@ LL | | }
    = note: the matched value is of type `Result<u32, Void>`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
-LL |     if let Ok(x) = x { /* */ }
+LL |     let x = if let Ok(x) = x { x } else { todo!() };
+   |     ++++++++++               ++++++++++++++++++++++
+help: alternatively, on nightly, you might want to use `#![feature(let_else)]` to handle the variant that isn't matched
    |
+LL |     let Ok(x) = x else { todo!() };
+   |                   ++++++++++++++++
 
 error: aborting due to 7 previous errors