From 4fe40635ef3c2cdbc2e3f62ca71f0e2235e70639 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Sun, 3 Jun 2018 23:31:49 -0400 Subject: [PATCH 1/7] Implementation of RFC 2086 - Allow Irrefutable Let patterns --- .../irrefutable-let-pattern.md | 23 ++++++++ src/librustc/lint/builtin.rs | 7 +++ src/librustc_mir/hair/pattern/check_match.rs | 57 ++++++++++++------- src/libsyntax/feature_gate.rs | 3 + ...e-gate-without_gate_irrefutable_pattern.rs | 17 ++++++ ...fail-no_gate_irrefutable_if_let_pattern.rs | 15 +++++ ...fail-with_gate_irrefutable_pattern_deny.rs | 17 ++++++ .../allow_irrefutable_let_patterns.rs | 22 +++++++ 8 files changed, 139 insertions(+), 22 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/irrefutable-let-pattern.md create mode 100644 src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs create mode 100644 src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs create mode 100644 src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs create mode 100644 src/test/run-pass/allow_irrefutable_let_patterns.rs diff --git a/src/doc/unstable-book/src/language-features/irrefutable-let-pattern.md b/src/doc/unstable-book/src/language-features/irrefutable-let-pattern.md new file mode 100644 index 0000000000000..13681c96811f9 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/irrefutable-let-pattern.md @@ -0,0 +1,23 @@ +# `irrefutable_let_pattern` + +The tracking issue for this feature is: [#44495] + +[#44495]: https://github.com/rust-lang/rust/issues/44495 + +------------------------ + +This feature changes the way that the irrefutable pattern is handled +in the `if let` and `while let` forms. The old way was to always error +but now with a tag the error-by-default lint can be switched off. + +```rust +#![feature(irrefutable_let_pattern)] + +fn main() { + #[allow(irrefutable_let_pattern)] + if let _ = 5 {} + + #[allow(irrefutable_let_pattern)] + while let _ = 5 {} +} +``` diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index de583e81ca831..d42567c6678c9 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -273,6 +273,12 @@ declare_lint! { "detects name collision with an existing but unstable method" } +declare_lint! { + pub IRREFUTABLE_LET_PATTERNS, + Deny, + "detects irrefutable patterns in if-let and while-let statements" +} + declare_lint! { pub UNUSED_LABELS, Allow, @@ -336,6 +342,7 @@ impl LintPass for HardwiredLints { BARE_TRAIT_OBJECTS, ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, UNSTABLE_NAME_COLLISIONS, + IRREFUTABLE_LET_PATTERNS, DUPLICATE_ASSOCIATED_TYPE_BINDINGS, ) } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 0a1139700984d..d5d69bf7f2b4b 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -369,43 +369,56 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, NotUseful => { match source { hir::MatchSource::IfLetDesugar { .. } => { - if printed_if_let_err { - // we already printed an irrefutable if-let pattern error. - // We don't want two, that's just confusing. + if cx.tcx.features().irrefutable_let_pattern { + cx.tcx.lint_node( + lint::builtin::IRREFUTABLE_LET_PATTERNS, + hir_pat.id, pat.span, + "irrefutable if-let pattern"); } else { - // find the first arm pattern so we can use its span - let &(ref first_arm_pats, _) = &arms[0]; - let first_pat = &first_arm_pats[0]; - let span = first_pat.0.span; - struct_span_err!(cx.tcx.sess, span, E0162, - "irrefutable if-let pattern") - .span_label(span, "irrefutable pattern") - .emit(); - printed_if_let_err = true; + if printed_if_let_err { + // we already printed an irrefutable if-let pattern error. + // We don't want two, that's just confusing. + } else { + // find the first arm pattern so we can use its span + let &(ref first_arm_pats, _) = &arms[0]; + let first_pat = &first_arm_pats[0]; + let span = first_pat.0.span; + struct_span_err!(cx.tcx.sess, span, E0162, + "irrefutable if-let pattern") + .span_label(span, "irrefutable pattern") + .emit(); + printed_if_let_err = true; + } } }, hir::MatchSource::WhileLetDesugar => { - // find the first arm pattern so we can use its span - let &(ref first_arm_pats, _) = &arms[0]; - let first_pat = &first_arm_pats[0]; - let span = first_pat.0.span; - // check which arm we're on. match arm_index { // The arm with the user-specified pattern. 0 => { cx.tcx.lint_node( - lint::builtin::UNREACHABLE_PATTERNS, + lint::builtin::UNREACHABLE_PATTERNS, hir_pat.id, pat.span, "unreachable pattern"); }, // The arm with the wildcard pattern. 1 => { - struct_span_err!(cx.tcx.sess, span, E0165, - "irrefutable while-let pattern") - .span_label(span, "irrefutable pattern") - .emit(); + if cx.tcx.features().irrefutable_let_pattern { + cx.tcx.lint_node( + lint::builtin::IRREFUTABLE_LET_PATTERNS, + hir_pat.id, pat.span, + "irrefutable while-let pattern"); + } else { + // find the first arm pattern so we can use its span + let &(ref first_arm_pats, _) = &arms[0]; + let first_pat = &first_arm_pats[0]; + let span = first_pat.0.span; + struct_span_err!(cx.tcx.sess, span, E0165, + "irrefutable while-let pattern") + .span_label(span, "irrefutable pattern") + .emit(); + } }, _ => bug!(), } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 51788b6063a33..f08a404a02a56 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -467,6 +467,9 @@ declare_features! ( // Scoped attributes (active, tool_attributes, "1.25.0", Some(44690), None), + // allow irrefutable patterns in if-let and while-let statements (RFC 2086) + (active, irrefutable_let_pattern, "1.27.0", Some(44495), None), + // Allows use of the :literal macro fragment specifier (RFC 1576) (active, macro_literal_matcher, "1.27.0", Some(35625), None), diff --git a/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs b/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs new file mode 100644 index 0000000000000..1facb6b152af3 --- /dev/null +++ b/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs @@ -0,0 +1,17 @@ +// gate-test-irrefutable_let_pattern + +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + #[allow(irrefutable_let_pattern)] + if let _ = 5 {} + //~^ ERROR 15:12: 15:13: irrefutable if-let pattern [E0162] +} diff --git a/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs b/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs new file mode 100644 index 0000000000000..71dcbf329c770 --- /dev/null +++ b/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// should-fail-irrefutable_let_pattern +fn main() { + if let _ = 5 {} + //~^ ERROR irrefutable if-let pattern [E0162] +} diff --git a/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs b/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs new file mode 100644 index 0000000000000..2f9b7f0628d7d --- /dev/null +++ b/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs @@ -0,0 +1,17 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(irrefutable_let_pattern)] + +// should-fail-irrefutable_let_pattern_with_gate +fn main() { + if let _ = 5 {} + //~^ ERROR irrefutable if-let pattern [irrefutable_let_pattern] +} diff --git a/src/test/run-pass/allow_irrefutable_let_patterns.rs b/src/test/run-pass/allow_irrefutable_let_patterns.rs new file mode 100644 index 0000000000000..3a4f226dfe653 --- /dev/null +++ b/src/test/run-pass/allow_irrefutable_let_patterns.rs @@ -0,0 +1,22 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(irrefutable_let_pattern)] + +// must-compile-successfully-irrefutable_let_pattern_with_gate +fn main() { + #[allow(irrefutable_let_pattern)] + if let _ = 5 {} + + #[allow(irrefutable_let_pattern)] + while let _ = 5 { + break; + } +} From e7c7f5f07139cd4afe6e8db13942a0ec250ded70 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 6 Jun 2018 22:03:42 -0400 Subject: [PATCH 2/7] Allowing attributes to be on if let statements --- src/libsyntax/parse/parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 95d519eae5851..4fdfc74ca5da7 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2597,7 +2597,7 @@ impl<'a> Parser<'a> { attrs.extend::>(expr.attrs.into()); expr.attrs = attrs; match expr.node { - ExprKind::If(..) | ExprKind::IfLet(..) => { + ExprKind::If(..) => { if !expr.attrs.is_empty() { // Just point to the first attribute in there... let span = expr.attrs[0].span; From 92d4ae2be2e9428c9ab523f04f917a41ac0f760e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 8 Jun 2018 11:25:35 -0400 Subject: [PATCH 3/7] rename `irrefutable_let_pattern` to `irrefutable_let_patterns` --- ...futable-let-pattern.md => irrefutable-let-patterns.md} | 8 ++++---- src/librustc_mir/hair/pattern/check_match.rs | 4 ++-- src/libsyntax/feature_gate.rs | 2 +- .../feature-gate-without_gate_irrefutable_pattern.rs | 4 ++-- .../should-fail-no_gate_irrefutable_if_let_pattern.rs | 2 +- .../should-fail-with_gate_irrefutable_pattern_deny.rs | 6 +++--- src/test/run-pass/allow_irrefutable_let_patterns.rs | 8 ++++---- 7 files changed, 17 insertions(+), 17 deletions(-) rename src/doc/unstable-book/src/language-features/{irrefutable-let-pattern.md => irrefutable-let-patterns.md} (74%) diff --git a/src/doc/unstable-book/src/language-features/irrefutable-let-pattern.md b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md similarity index 74% rename from src/doc/unstable-book/src/language-features/irrefutable-let-pattern.md rename to src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md index 13681c96811f9..0d782e1c5395f 100644 --- a/src/doc/unstable-book/src/language-features/irrefutable-let-pattern.md +++ b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md @@ -1,4 +1,4 @@ -# `irrefutable_let_pattern` +# `irrefutable_let_patterns` The tracking issue for this feature is: [#44495] @@ -11,13 +11,13 @@ in the `if let` and `while let` forms. The old way was to always error but now with a tag the error-by-default lint can be switched off. ```rust -#![feature(irrefutable_let_pattern)] +#![feature(irrefutable_let_patterns)] fn main() { - #[allow(irrefutable_let_pattern)] + #[allow(irrefutable_let_patterns)] if let _ = 5 {} - #[allow(irrefutable_let_pattern)] + #[allow(irrefutable_let_patterns)] while let _ = 5 {} } ``` diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index d5d69bf7f2b4b..895f050d3997d 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -369,7 +369,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, NotUseful => { match source { hir::MatchSource::IfLetDesugar { .. } => { - if cx.tcx.features().irrefutable_let_pattern { + if cx.tcx.features().irrefutable_let_patterns { cx.tcx.lint_node( lint::builtin::IRREFUTABLE_LET_PATTERNS, hir_pat.id, pat.span, @@ -404,7 +404,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, }, // The arm with the wildcard pattern. 1 => { - if cx.tcx.features().irrefutable_let_pattern { + if cx.tcx.features().irrefutable_let_patterns { cx.tcx.lint_node( lint::builtin::IRREFUTABLE_LET_PATTERNS, hir_pat.id, pat.span, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f08a404a02a56..01820379c96be 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -468,7 +468,7 @@ declare_features! ( (active, tool_attributes, "1.25.0", Some(44690), None), // allow irrefutable patterns in if-let and while-let statements (RFC 2086) - (active, irrefutable_let_pattern, "1.27.0", Some(44495), None), + (active, irrefutable_let_patterns, "1.27.0", Some(44495), None), // Allows use of the :literal macro fragment specifier (RFC 1576) (active, macro_literal_matcher, "1.27.0", Some(35625), None), diff --git a/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs b/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs index 1facb6b152af3..7cd026e21d6d8 100644 --- a/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs +++ b/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs @@ -1,4 +1,4 @@ -// gate-test-irrefutable_let_pattern +// gate-test-irrefutable_let_patterns // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at @@ -11,7 +11,7 @@ // except according to those terms. fn main() { - #[allow(irrefutable_let_pattern)] + #[allow(irrefutable_let_patterns)] if let _ = 5 {} //~^ ERROR 15:12: 15:13: irrefutable if-let pattern [E0162] } diff --git a/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs b/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs index 71dcbf329c770..8c9a24f4e7222 100644 --- a/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs +++ b/src/test/compile-fail/should-fail-no_gate_irrefutable_if_let_pattern.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// should-fail-irrefutable_let_pattern +// should-fail-irrefutable_let_patterns fn main() { if let _ = 5 {} //~^ ERROR irrefutable if-let pattern [E0162] diff --git a/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs b/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs index 2f9b7f0628d7d..6f95f10c0d93f 100644 --- a/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs +++ b/src/test/compile-fail/should-fail-with_gate_irrefutable_pattern_deny.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(irrefutable_let_pattern)] +#![feature(irrefutable_let_patterns)] -// should-fail-irrefutable_let_pattern_with_gate +// should-fail-irrefutable_let_patterns_with_gate fn main() { if let _ = 5 {} - //~^ ERROR irrefutable if-let pattern [irrefutable_let_pattern] + //~^ ERROR irrefutable if-let pattern [irrefutable_let_patterns] } diff --git a/src/test/run-pass/allow_irrefutable_let_patterns.rs b/src/test/run-pass/allow_irrefutable_let_patterns.rs index 3a4f226dfe653..689a54d60f3fc 100644 --- a/src/test/run-pass/allow_irrefutable_let_patterns.rs +++ b/src/test/run-pass/allow_irrefutable_let_patterns.rs @@ -8,14 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(irrefutable_let_pattern)] +#![feature(irrefutable_let_patterns)] -// must-compile-successfully-irrefutable_let_pattern_with_gate +// must-compile-successfully-irrefutable_let_patterns_with_gate fn main() { - #[allow(irrefutable_let_pattern)] + #[allow(irrefutable_let_patterns)] if let _ = 5 {} - #[allow(irrefutable_let_pattern)] + #[allow(irrefutable_let_patterns)] while let _ = 5 { break; } From d6f13c0e207bff8b09eded9bd62d61f9d6d04b4c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 12 Jun 2018 14:49:17 -0400 Subject: [PATCH 4/7] update wording, do not change parser --- .../irrefutable-let-patterns.md | 17 +++++++++++------ src/libsyntax/parse/parser.rs | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md index 0d782e1c5395f..716deaba01e10 100644 --- a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md +++ b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md @@ -6,18 +6,23 @@ The tracking issue for this feature is: [#44495] ------------------------ -This feature changes the way that the irrefutable pattern is handled -in the `if let` and `while let` forms. The old way was to always error -but now with a tag the error-by-default lint can be switched off. +This feature changes the way that "irrefutable patterns" are handled +in the `if let` and `while let` forms. An *irrefutable pattern* is one +that cannot fail to match -- for example, the `_` pattern matches any +value, and hence it is "irrefutable". Without this feature, using an +irrefutable pattern in an `if let` gives a hard error (since often +this indicates programmer error). But when the feature is enabled, the +error becomes a lint (since in some cases irrefutable patterns are +expected). This means you can use `#[allow]` to silence the lint: ```rust #![feature(irrefutable_let_patterns)] +#[allow(irrefutable_let_patterns)] fn main() { - #[allow(irrefutable_let_patterns)] + // These two examples used to be errors, but now they + // trigger a lint (that is allowed): if let _ = 5 {} - - #[allow(irrefutable_let_patterns)] while let _ = 5 {} } ``` diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4fdfc74ca5da7..95d519eae5851 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2597,7 +2597,7 @@ impl<'a> Parser<'a> { attrs.extend::>(expr.attrs.into()); expr.attrs = attrs; match expr.node { - ExprKind::If(..) => { + ExprKind::If(..) | ExprKind::IfLet(..) => { if !expr.attrs.is_empty() { // Just point to the first attribute in there... let span = expr.attrs[0].span; From 84de498832cfc12bf2e4e71eb7bdcd8f0fa7a38d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 15 Jun 2018 09:49:18 -0400 Subject: [PATCH 5/7] fix `allow(irrefutable_let_patterns)` --- src/test/run-pass/allow_irrefutable_let_patterns.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/run-pass/allow_irrefutable_let_patterns.rs b/src/test/run-pass/allow_irrefutable_let_patterns.rs index 689a54d60f3fc..ea114b63be73a 100644 --- a/src/test/run-pass/allow_irrefutable_let_patterns.rs +++ b/src/test/run-pass/allow_irrefutable_let_patterns.rs @@ -11,11 +11,10 @@ #![feature(irrefutable_let_patterns)] // must-compile-successfully-irrefutable_let_patterns_with_gate +#[allow(irrefutable_let_patterns)] fn main() { - #[allow(irrefutable_let_patterns)] if let _ = 5 {} - #[allow(irrefutable_let_patterns)] while let _ = 5 { break; } From 01fbeb5b7ac85a67c9b46acbed5d9eeee4e844ce Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 15 Jun 2018 10:56:12 -0400 Subject: [PATCH 6/7] Moving allow statemate to the function block --- .../feature-gate-without_gate_irrefutable_pattern.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs b/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs index 7cd026e21d6d8..7bcddbb6a2f16 100644 --- a/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs +++ b/src/test/compile-fail/feature-gate-without_gate_irrefutable_pattern.rs @@ -10,8 +10,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(irrefutable_let_patterns)] fn main() { - #[allow(irrefutable_let_patterns)] if let _ = 5 {} //~^ ERROR 15:12: 15:13: irrefutable if-let pattern [E0162] } From 91680347a7ef48ddffd9ff06eedb54a550891cf1 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 25 Jun 2018 17:33:49 -0400 Subject: [PATCH 7/7] make the `while let` loop terminate --- .../src/language-features/irrefutable-let-patterns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md index 716deaba01e10..46b843778e810 100644 --- a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md +++ b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md @@ -23,6 +23,6 @@ fn main() { // These two examples used to be errors, but now they // trigger a lint (that is allowed): if let _ = 5 {} - while let _ = 5 {} + while let _ = 5 { break; } } ```