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

Stabilise irrefutable if-let and while-let patterns #57535

Merged
merged 2 commits into from Jan 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view

This file was deleted.

2 changes: 1 addition & 1 deletion src/librustc/lint/builtin.rs
Expand Up @@ -286,7 +286,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
Expand Up @@ -325,11 +325,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:

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

Expand All @@ -352,11 +354,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
49 changes: 12 additions & 37 deletions src/librustc_mir/hair/pattern/check_match.rs
Expand Up @@ -350,7 +350,6 @@ 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 = smallvec![pat];
Expand All @@ -359,27 +358,12 @@ 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,
"irrefutable if-let pattern",
);
}

hir::MatchSource::WhileLetDesugar => {
Expand All @@ -394,21 +378,12 @@ 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,
"irrefutable while-let pattern",
);
},
_ => bug!(),
}
Expand Down
5 changes: 2 additions & 3 deletions src/libsyntax/feature_gate.rs
Expand Up @@ -414,9 +414,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 @@ -684,6 +681,8 @@ declare_features! (
(accepted, underscore_imports, "1.33.0", Some(48216), None),
// Allows `#[repr(packed(N))]` attribute on structs.
(accepted, repr_packed, "1.33.0", Some(33158), None),
// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
(accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
(accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
// `#[cfg_attr(predicate, multiple, attributes, here)]`
Expand Down
12 changes: 0 additions & 12 deletions src/test/run-pass/binding/allow_irrefutable_let_patterns.rs

This file was deleted.

8 changes: 0 additions & 8 deletions src/test/ui/error-codes/E0162.rs

This file was deleted.

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

This file was deleted.

9 changes: 0 additions & 9 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.

This file was deleted.

14 changes: 8 additions & 6 deletions src/test/ui/if/if-let.rs
@@ -1,3 +1,5 @@
// compile-pass

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

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

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

if let a = 1 { //~ ERROR irrefutable if-let
if let a = 1 { //~ WARN irrefutable if-let
println!("irrefutable pattern");
} else if true {
println!("else-if in irrefutable if-let");
Expand All @@ -33,13 +35,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 { //~ WARN irrefutable if-let
println!("irrefutable pattern");
}

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

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

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

error[E0162]: irrefutable if-let pattern
--> $DIR/if-let.rs:36:19
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:28:5
|
LL | } else if let a = 1 { //~ ERROR irrefutable if-let
| ^ irrefutable pattern
LL | / if let a = 1 { //~ WARN 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:42:19
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:38:12
|
LL | } else if let a = 1 { //~ ERROR irrefutable if-let
| ^ irrefutable pattern
LL | } else if let a = 1 { //~ WARN irrefutable if-let
| ____________^
LL | | println!("irrefutable pattern");
LL | | }
| |_____^

error: aborting due to 6 previous errors
warning: irrefutable if-let pattern
--> $DIR/if-let.rs:44:12
|
LL | } else if let a = 1 { //~ WARN 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
Expand Up @@ -10,5 +10,5 @@ fn main() {

[(); return while let Some(n) = Some(0) {}];
//~^ ERROR return statement outside of function body
//~^^ ERROR irrefutable while-let pattern
//~^^ WARN irrefutable while-let pattern
}
13 changes: 7 additions & 6 deletions src/test/ui/issues/issue-51714.stderr
Expand Up @@ -22,13 +22,14 @@ error[E0572]: return statement outside of function body
LL | [(); return while let Some(n) = Some(0) {}];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0165]: irrefutable while-let pattern
--> $DIR/issue-51714.rs:11:27
warning: irrefutable while-let pattern
--> $DIR/issue-51714.rs:11:17
|
LL | [(); return while let Some(n) = Some(0) {}];
| ^^^^^^^ irrefutable pattern
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(irrefutable_let_patterns)] on by default

error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

Some errors occurred: E0165, E0572.
For more information about an error, try `rustc --explain E0165`.
For more information about this error, try `rustc --explain E0572`.