Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize allow irrefutable if-let patterns #55639

Closed
wants to merge 11 commits into from

This file was deleted.

2 changes: 1 addition & 1 deletion src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ declare_lint! {

declare_lint! {
pub IRREFUTABLE_LET_PATTERNS,
Deny,
Warn,
"detects irrefutable patterns in if-let and while-let statements"
}

Expand Down
8 changes: 6 additions & 2 deletions src/librustc_mir/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,13 @@ match Some(42) {
"##,

E0162: r##"
#### Note: this error code is no longer emitted by the compiler.

An if-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular `let`-binding instead. For instance:
Nokel81 marked this conversation as resolved.
Show resolved Hide resolved

```compile_fail,E0162
```compile_pass
struct Irrefutable(i32);
let irr = Irrefutable(0);

Expand All @@ -362,11 +364,13 @@ println!("{}", x);
"##,

E0165: r##"
#### Note: this error code is no longer emitted by the compiler.

A while-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular `let`-binding inside a `loop` instead. For instance:

```compile_fail,E0165
```compile_pass,no_run
struct Irrefutable(i32);
let irr = Irrefutable(0);

Expand Down
46 changes: 9 additions & 37 deletions src/librustc_mir/hair/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
{
let mut seen = Matrix::empty();
let mut catchall = None;
let mut printed_if_let_err = false;

for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
for &(pat, hir_pat) in pats {
let v = vec![pat];
Expand All @@ -373,27 +373,10 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
NotUseful => {
match source {
hir::MatchSource::IfLetDesugar { .. } => {
if cx.tcx.features().irrefutable_let_patterns {
cx.tcx.lint_node(
lint::builtin::IRREFUTABLE_LET_PATTERNS,
hir_pat.id, pat.span,
"irrefutable if-let pattern");
} else {
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;
}
}
cx.tcx.lint_node(
lint::builtin::IRREFUTABLE_LET_PATTERNS,
hir_pat.id, pat.span,
Nokel81 marked this conversation as resolved.
Show resolved Hide resolved
"irrefutable if-let pattern");
}

hir::MatchSource::WhileLetDesugar => {
Expand All @@ -408,21 +391,10 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
},
// The arm with the wildcard pattern.
1 => {
if cx.tcx.features().irrefutable_let_patterns {
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();
}
cx.tcx.lint_node(
lint::builtin::IRREFUTABLE_LET_PATTERNS,
hir_pat.id, pat.span,
Nokel81 marked this conversation as resolved.
Show resolved Hide resolved
"irrefutable while-let pattern");
},
_ => bug!(),
}
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,6 @@ declare_features! (
// `#[doc(alias = "...")]`
(active, doc_alias, "1.27.0", Some(50146), None),

// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
(active, irrefutable_let_patterns, "1.27.0", Some(44495), None),

// inconsistent bounds in where clauses
(active, trivial_bounds, "1.28.0", Some(48214), None),

Expand Down Expand Up @@ -686,6 +683,9 @@ declare_features! (
(accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
// Allows use of the `:literal` macro fragment specifier (RFC 1576).
(accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
// Allows irrefutable patterns in if-let and while-let statements (RFC 2086)
(accepted, irrefutable_let_patterns, "1.32.0", Some(44495), None),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(accepted, irrefutable_let_patterns, "1.32.0", Some(44495), None),
(accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),

It slipped so you'll have to bump the version.

// Use `?` as the Kleene "at most one" operator
// Integer match exhaustiveness checking (RFC 2591)
(accepted, exhaustive_integer_patterns, "1.32.0", Some(50907), None),
// Use `?` as the Kleene "at most one" operator.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// gate-test-irrefutable_let_patterns

// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -12,6 +10,7 @@

#[allow(irrefutable_let_patterns)]
fn main() {
if let _ = 5 {}
//~^ ERROR 15:12: 15:13: irrefutable if-let pattern [E0162]
if let _ = 5 {
let _x = 1;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -8,8 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// should-fail-irrefutable_let_patterns
#[allow(irrefutable_let_patterns)]
fn main() {
if let _ = 5 {}
//~^ ERROR irrefutable if-let pattern [E0162]
while let _ = 5 {
break;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
warning: the feature `irrefutable_let_patterns` has been stable since 1.32.0 and no longer requires an attribute to enable
Centril marked this conversation as resolved.
Show resolved Hide resolved

--> $DIR/allow_irrefutable_let_patterns.rs:12:12
|
LL | #![feature(irrefutable_let_patterns)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(stable_features)] on by default
9 changes: 0 additions & 9 deletions src/test/ui/error-codes/E0162.stderr

This file was deleted.

19 changes: 0 additions & 19 deletions src/test/ui/error-codes/E0165.rs

This file was deleted.

9 changes: 0 additions & 9 deletions src/test/ui/error-codes/E0165.stderr

This file was deleted.

This file was deleted.

14 changes: 8 additions & 6 deletions src/test/ui/if/if-let.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-pass

fn macros() {
macro_rules! foo{
($p:pat, $e:expr, $b:block) => {{
Expand All @@ -20,20 +22,20 @@ fn macros() {
}}
}

foo!(a, 1, { //~ ERROR irrefutable if-let
foo!(a, 1, { //~ warning irrefutable if-let
println!("irrefutable pattern");
});
bar!(a, 1, { //~ ERROR irrefutable if-let
bar!(a, 1, { //~ warning irrefutable if-let
println!("irrefutable pattern");
});
}

pub fn main() {
if let a = 1 { //~ ERROR irrefutable if-let
if let a = 1 { //~ warning irrefutable if-let
println!("irrefutable pattern");
}

if let a = 1 { //~ ERROR irrefutable if-let
if let a = 1 { //~ warning irrefutable if-let
println!("irrefutable pattern");
} else if true {
println!("else-if in irrefutable if-let");
Expand All @@ -43,13 +45,13 @@ pub fn main() {

if let 1 = 2 {
println!("refutable pattern");
} else if let a = 1 { //~ ERROR irrefutable if-let
} else if let a = 1 { //~ warning irrefutable if-let
println!("irrefutable pattern");
}

if true {
println!("if");
} else if let a = 1 { //~ ERROR irrefutable if-let
} else if let a = 1 { //~ warning irrefutable if-let
println!("irrefutable pattern");
}
}
77 changes: 50 additions & 27 deletions src/test/ui/if/if-let.stderr
Original file line number Diff line number Diff line change
@@ -1,39 +1,62 @@
error[E0162]: irrefutable if-let pattern
--> $DIR/if-let.rs:23:10
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:16:13
|
LL | foo!(a, 1, { //~ ERROR irrefutable if-let
| ^ irrefutable pattern

error[E0162]: irrefutable if-let pattern
--> $DIR/if-let.rs:26:10
LL | if let $p = $e $b
| ^^
...
LL | / foo!(a, 1, { //~ warning irrefutable if-let
LL | | println!("irrefutable pattern");
LL | | });
| |_______- in this macro invocation
|
LL | bar!(a, 1, { //~ ERROR irrefutable if-let
| ^ irrefutable pattern
= note: #[warn(irrefutable_let_patterns)] on by default

error[E0162]: irrefutable if-let pattern
--> $DIR/if-let.rs:32:12
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:16:13
|
LL | if let a = 1 { //~ ERROR irrefutable if-let
| ^ irrefutable pattern
LL | if let $p = $e $b
| ^^
...
LL | / bar!(a, 1, { //~ warning irrefutable if-let
LL | | println!("irrefutable pattern");
LL | | });
| |_______- in this macro invocation

error[E0162]: irrefutable if-let pattern
--> $DIR/if-let.rs:36:12
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:34:5
|
LL | if let a = 1 { //~ ERROR irrefutable if-let
| ^ irrefutable pattern
LL | / if let a = 1 { //~ warning irrefutable if-let
LL | | println!("irrefutable pattern");
LL | | }
| |_____^

error[E0162]: irrefutable if-let pattern
--> $DIR/if-let.rs:46:19
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:38:5
|
LL | } else if let a = 1 { //~ ERROR irrefutable if-let
| ^ irrefutable pattern
LL | / if let a = 1 { //~ warning irrefutable if-let
LL | | println!("irrefutable pattern");
LL | | } else if true {
LL | | println!("else-if in irrefutable if-let");
LL | | } else {
LL | | println!("else in irrefutable if-let");
LL | | }
| |_____^

error[E0162]: irrefutable if-let pattern
--> $DIR/if-let.rs:52:19
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:48:12
|
LL | } else if let a = 1 { //~ ERROR irrefutable if-let
| ^ irrefutable pattern
LL | } else if let a = 1 { //~ warning irrefutable if-let
| ____________^
LL | | println!("irrefutable pattern");
LL | | }
| |_____^

error: aborting due to 6 previous errors
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:54:12
|
LL | } else if let a = 1 { //~ warning irrefutable if-let
| ____________^
LL | | println!("irrefutable pattern");
LL | | }
| |_____^

For more information about this error, try `rustc --explain E0162`.
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-51714.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ fn main() {

[(); return while let Some(n) = Some(0) {}];
//~^ ERROR return statement outside of function body
//~^^ ERROR irrefutable while-let pattern
//~^^ warning irrefutable while-let pattern
}
Loading