Stabilise irrefutable if-let and while-let patterns
This stabilises RFC 2086 (https://github.com/rust-lang/rust/issues/44495). Co-Authored-By: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
b43986184b
commit
afcb938116
30 changed files with 175 additions and 239 deletions
|
@ -1,28 +0,0 @@
|
||||||
# `irrefutable_let_patterns`
|
|
||||||
|
|
||||||
The tracking issue for this feature is: [#44495]
|
|
||||||
|
|
||||||
[#44495]: https://github.com/rust-lang/rust/issues/44495
|
|
||||||
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
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() {
|
|
||||||
// These two examples used to be errors, but now they
|
|
||||||
// trigger a lint (that is allowed):
|
|
||||||
if let _ = 5 {}
|
|
||||||
while let _ = 5 { break; }
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -286,7 +286,7 @@ declare_lint! {
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub IRREFUTABLE_LET_PATTERNS,
|
pub IRREFUTABLE_LET_PATTERNS,
|
||||||
Deny,
|
Warn,
|
||||||
"detects irrefutable patterns in if-let and while-let statements"
|
"detects irrefutable patterns in if-let and while-let statements"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -325,11 +325,13 @@ match Some(42) {
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
E0162: r##"
|
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
|
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 was successful. If the match is irrefutable (when it cannot fail to
|
||||||
match), use a regular `let`-binding instead. For instance:
|
match), use a regular `let`-binding instead. For instance:
|
||||||
|
|
||||||
```compile_fail,E0162
|
```compile_pass
|
||||||
struct Irrefutable(i32);
|
struct Irrefutable(i32);
|
||||||
let irr = Irrefutable(0);
|
let irr = Irrefutable(0);
|
||||||
|
|
||||||
|
@ -352,11 +354,13 @@ println!("{}", x);
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
E0165: r##"
|
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
|
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 was successful. If the match is irrefutable (when it cannot fail to
|
||||||
match), use a regular `let`-binding inside a `loop` instead. For instance:
|
match), use a regular `let`-binding inside a `loop` instead. For instance:
|
||||||
|
|
||||||
```compile_fail,E0165
|
```compile_pass,no_run
|
||||||
struct Irrefutable(i32);
|
struct Irrefutable(i32);
|
||||||
let irr = Irrefutable(0);
|
let irr = Irrefutable(0);
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,6 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||||
{
|
{
|
||||||
let mut seen = Matrix::empty();
|
let mut seen = Matrix::empty();
|
||||||
let mut catchall = None;
|
let mut catchall = None;
|
||||||
let mut printed_if_let_err = false;
|
|
||||||
for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
|
for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
|
||||||
for &(pat, hir_pat) in pats {
|
for &(pat, hir_pat) in pats {
|
||||||
let v = smallvec![pat];
|
let v = smallvec![pat];
|
||||||
|
@ -359,27 +358,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||||
NotUseful => {
|
NotUseful => {
|
||||||
match source {
|
match source {
|
||||||
hir::MatchSource::IfLetDesugar { .. } => {
|
hir::MatchSource::IfLetDesugar { .. } => {
|
||||||
if cx.tcx.features().irrefutable_let_patterns {
|
cx.tcx.lint_node(
|
||||||
cx.tcx.lint_node(
|
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
||||||
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
hir_pat.id,
|
||||||
hir_pat.id, pat.span,
|
pat.span,
|
||||||
"irrefutable if-let pattern");
|
"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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::MatchSource::WhileLetDesugar => {
|
hir::MatchSource::WhileLetDesugar => {
|
||||||
|
@ -394,21 +378,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
||||||
},
|
},
|
||||||
// The arm with the wildcard pattern.
|
// The arm with the wildcard pattern.
|
||||||
1 => {
|
1 => {
|
||||||
if cx.tcx.features().irrefutable_let_patterns {
|
cx.tcx.lint_node(
|
||||||
cx.tcx.lint_node(
|
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
||||||
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
hir_pat.id,
|
||||||
hir_pat.id, pat.span,
|
pat.span,
|
||||||
"irrefutable while-let pattern");
|
"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!(),
|
_ => bug!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,9 +414,6 @@ declare_features! (
|
||||||
// `#[doc(alias = "...")]`
|
// `#[doc(alias = "...")]`
|
||||||
(active, doc_alias, "1.27.0", Some(50146), None),
|
(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
|
// inconsistent bounds in where clauses
|
||||||
(active, trivial_bounds, "1.28.0", Some(48214), None),
|
(active, trivial_bounds, "1.28.0", Some(48214), None),
|
||||||
|
|
||||||
|
@ -684,6 +681,8 @@ declare_features! (
|
||||||
(accepted, underscore_imports, "1.33.0", Some(48216), None),
|
(accepted, underscore_imports, "1.33.0", Some(48216), None),
|
||||||
// Allows `#[repr(packed(N))]` attribute on structs.
|
// Allows `#[repr(packed(N))]` attribute on structs.
|
||||||
(accepted, repr_packed, "1.33.0", Some(33158), None),
|
(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.
|
// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
|
||||||
(accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
|
(accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
|
||||||
// `#[cfg_attr(predicate, multiple, attributes, here)]`
|
// `#[cfg_attr(predicate, multiple, attributes, here)]`
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
// run-pass
|
|
||||||
#![feature(irrefutable_let_patterns)]
|
|
||||||
|
|
||||||
// must-compile-successfully-irrefutable_let_patterns_with_gate
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
fn main() {
|
|
||||||
if let _ = 5 {}
|
|
||||||
|
|
||||||
while let _ = 5 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
struct Irrefutable(i32);
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let irr = Irrefutable(0);
|
|
||||||
if let Irrefutable(x) = irr { //~ ERROR E0162
|
|
||||||
println!("{}", x);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
error[E0162]: irrefutable if-let pattern
|
|
||||||
--> $DIR/E0162.rs:5:12
|
|
||||||
|
|
|
||||||
LL | if let Irrefutable(x) = irr { //~ ERROR E0162
|
|
||||||
| ^^^^^^^^^^^^^^ irrefutable pattern
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0162`.
|
|
|
@ -1,9 +0,0 @@
|
||||||
struct Irrefutable(i32);
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let irr = Irrefutable(0);
|
|
||||||
while let Irrefutable(x) = irr { //~ ERROR E0165
|
|
||||||
//~| irrefutable pattern
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
error[E0165]: irrefutable while-let pattern
|
|
||||||
--> $DIR/E0165.rs:5:15
|
|
||||||
|
|
|
||||||
LL | while let Irrefutable(x) = irr { //~ ERROR E0165
|
|
||||||
| ^^^^^^^^^^^^^^ irrefutable pattern
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0165`.
|
|
|
@ -1,8 +0,0 @@
|
||||||
// gate-test-irrefutable_let_patterns
|
|
||||||
|
|
||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
|
||||||
fn main() {
|
|
||||||
if let _ = 5 {}
|
|
||||||
//~^ ERROR irrefutable if-let pattern [E0162]
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
error[E0162]: irrefutable if-let pattern
|
|
||||||
--> $DIR/feature-gate-without_gate_irrefutable_pattern.rs:6:12
|
|
||||||
|
|
|
||||||
LL | if let _ = 5 {}
|
|
||||||
| ^ irrefutable pattern
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0162`.
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// compile-pass
|
||||||
|
|
||||||
fn macros() {
|
fn macros() {
|
||||||
macro_rules! foo{
|
macro_rules! foo{
|
||||||
($p:pat, $e:expr, $b:block) => {{
|
($p:pat, $e:expr, $b:block) => {{
|
||||||
|
@ -10,20 +12,20 @@ fn macros() {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
foo!(a, 1, { //~ ERROR irrefutable if-let
|
foo!(a, 1, { //~ WARN irrefutable if-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
});
|
});
|
||||||
bar!(a, 1, { //~ ERROR irrefutable if-let
|
bar!(a, 1, { //~ WARN irrefutable if-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
if let a = 1 { //~ ERROR irrefutable if-let
|
if let a = 1 { //~ WARN irrefutable if-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let a = 1 { //~ ERROR irrefutable if-let
|
if let a = 1 { //~ WARN irrefutable if-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
} else if true {
|
} else if true {
|
||||||
println!("else-if in irrefutable if-let");
|
println!("else-if in irrefutable if-let");
|
||||||
|
@ -33,13 +35,13 @@ pub fn main() {
|
||||||
|
|
||||||
if let 1 = 2 {
|
if let 1 = 2 {
|
||||||
println!("refutable pattern");
|
println!("refutable pattern");
|
||||||
} else if let a = 1 { //~ ERROR irrefutable if-let
|
} else if let a = 1 { //~ WARN irrefutable if-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
}
|
}
|
||||||
|
|
||||||
if true {
|
if true {
|
||||||
println!("if");
|
println!("if");
|
||||||
} else if let a = 1 { //~ ERROR irrefutable if-let
|
} else if let a = 1 { //~ WARN irrefutable if-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,62 @@
|
||||||
error[E0162]: irrefutable if-let pattern
|
warning: irrefutable if-let pattern
|
||||||
--> $DIR/if-let.rs:13:10
|
--> $DIR/if-let.rs:6:13
|
||||||
|
|
|
|
||||||
LL | foo!(a, 1, { //~ ERROR irrefutable if-let
|
LL | if let $p = $e $b
|
||||||
| ^ irrefutable pattern
|
| ^^
|
||||||
|
...
|
||||||
error[E0162]: irrefutable if-let pattern
|
LL | / foo!(a, 1, { //~ WARN irrefutable if-let
|
||||||
--> $DIR/if-let.rs:16:10
|
LL | | println!("irrefutable pattern");
|
||||||
|
LL | | });
|
||||||
|
| |_______- in this macro invocation
|
||||||
|
|
|
|
||||||
LL | bar!(a, 1, { //~ ERROR irrefutable if-let
|
= note: #[warn(irrefutable_let_patterns)] on by default
|
||||||
| ^ irrefutable pattern
|
|
||||||
|
|
||||||
error[E0162]: irrefutable if-let pattern
|
warning: irrefutable if-let pattern
|
||||||
--> $DIR/if-let.rs:22:12
|
--> $DIR/if-let.rs:6:13
|
||||||
|
|
|
|
||||||
LL | if let a = 1 { //~ ERROR irrefutable if-let
|
LL | if let $p = $e $b
|
||||||
| ^ irrefutable pattern
|
| ^^
|
||||||
|
...
|
||||||
|
LL | / bar!(a, 1, { //~ WARN irrefutable if-let
|
||||||
|
LL | | println!("irrefutable pattern");
|
||||||
|
LL | | });
|
||||||
|
| |_______- in this macro invocation
|
||||||
|
|
||||||
error[E0162]: irrefutable if-let pattern
|
warning: irrefutable if-let pattern
|
||||||
--> $DIR/if-let.rs:26:12
|
--> $DIR/if-let.rs:24:5
|
||||||
|
|
|
|
||||||
LL | if let a = 1 { //~ ERROR irrefutable if-let
|
LL | / if let a = 1 { //~ WARN irrefutable if-let
|
||||||
| ^ irrefutable pattern
|
LL | | println!("irrefutable pattern");
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
error[E0162]: irrefutable if-let pattern
|
warning: irrefutable if-let pattern
|
||||||
--> $DIR/if-let.rs:36:19
|
--> $DIR/if-let.rs:28:5
|
||||||
|
|
|
|
||||||
LL | } else if let a = 1 { //~ ERROR irrefutable if-let
|
LL | / if let a = 1 { //~ WARN irrefutable if-let
|
||||||
| ^ irrefutable pattern
|
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
|
warning: irrefutable if-let pattern
|
||||||
--> $DIR/if-let.rs:42:19
|
--> $DIR/if-let.rs:38:12
|
||||||
|
|
|
|
||||||
LL | } else if let a = 1 { //~ ERROR irrefutable if-let
|
LL | } else if let a = 1 { //~ WARN irrefutable if-let
|
||||||
| ^ irrefutable pattern
|
| ____________^
|
||||||
|
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`.
|
|
||||||
|
|
|
@ -10,5 +10,5 @@ fn main() {
|
||||||
|
|
||||||
[(); return while let Some(n) = Some(0) {}];
|
[(); return while let Some(n) = Some(0) {}];
|
||||||
//~^ ERROR return statement outside of function body
|
//~^ ERROR return statement outside of function body
|
||||||
//~^^ ERROR irrefutable while-let pattern
|
//~^^ WARN irrefutable while-let pattern
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,14 @@ error[E0572]: return statement outside of function body
|
||||||
LL | [(); return while let Some(n) = Some(0) {}];
|
LL | [(); return while let Some(n) = Some(0) {}];
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0165]: irrefutable while-let pattern
|
warning: irrefutable while-let pattern
|
||||||
--> $DIR/issue-51714.rs:11:27
|
--> $DIR/issue-51714.rs:11:17
|
||||||
|
|
|
|
||||||
LL | [(); return while let Some(n) = Some(0) {}];
|
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 this error, try `rustc --explain E0572`.
|
||||||
For more information about an error, try `rustc --explain E0165`.
|
|
||||||
|
|
9
src/test/ui/pattern/deny-irrefutable-let-patterns.rs
Normal file
9
src/test/ui/pattern/deny-irrefutable-let-patterns.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#![deny(irrefutable_let_patterns)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if let _ = 5 {} //~ ERROR irrefutable if-let pattern
|
||||||
|
|
||||||
|
while let _ = 5 { //~ ERROR irrefutable while-let pattern
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
22
src/test/ui/pattern/deny-irrefutable-let-patterns.stderr
Normal file
22
src/test/ui/pattern/deny-irrefutable-let-patterns.stderr
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
error: irrefutable if-let pattern
|
||||||
|
--> $DIR/deny-irrefutable-let-patterns.rs:4:5
|
||||||
|
|
|
||||||
|
LL | if let _ = 5 {} //~ ERROR irrefutable if-let pattern
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/deny-irrefutable-let-patterns.rs:1:9
|
||||||
|
|
|
||||||
|
LL | #![deny(irrefutable_let_patterns)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: irrefutable while-let pattern
|
||||||
|
--> $DIR/deny-irrefutable-let-patterns.rs:6:5
|
||||||
|
|
|
||||||
|
LL | / while let _ = 5 { //~ ERROR irrefutable while-let pattern
|
||||||
|
LL | | break;
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#![feature(irrefutable_let_patterns)]
|
// run-pass
|
||||||
|
|
||||||
#![feature(type_alias_enum_variants)]
|
#![feature(type_alias_enum_variants)]
|
||||||
|
|
||||||
#![allow(irrefutable_let_patterns)]
|
#![allow(irrefutable_let_patterns)]
|
11
src/test/ui/pattern/irrefutable-let-patterns.rs
Normal file
11
src/test/ui/pattern/irrefutable-let-patterns.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
#![allow(irrefutable_let_patterns)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if let _ = 5 {}
|
||||||
|
|
||||||
|
while let _ = 5 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
// Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up
|
// Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up
|
||||||
// with examples easier.
|
// with examples easier.
|
||||||
#![feature(irrefutable_let_patterns)]
|
|
||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: ambiguous use of `&&`
|
error: ambiguous use of `&&`
|
||||||
--> $DIR/syntax-ambiguity-2015.rs:11:47
|
--> $DIR/syntax-ambiguity-2015.rs:10:47
|
||||||
|
|
|
|
||||||
LL | if let Range { start: _, end: _ } = true..true && false { }
|
LL | if let Range { start: _, end: _ } = true..true && false { }
|
||||||
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
|
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
|
||||||
|
@ -8,7 +8,7 @@ LL | if let Range { start: _, end: _ } = true..true && false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `||`
|
error: ambiguous use of `||`
|
||||||
--> $DIR/syntax-ambiguity-2015.rs:14:47
|
--> $DIR/syntax-ambiguity-2015.rs:13:47
|
||||||
|
|
|
|
||||||
LL | if let Range { start: _, end: _ } = true..true || false { }
|
LL | if let Range { start: _, end: _ } = true..true || false { }
|
||||||
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
|
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
|
||||||
|
@ -17,7 +17,7 @@ LL | if let Range { start: _, end: _ } = true..true || false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `&&`
|
error: ambiguous use of `&&`
|
||||||
--> $DIR/syntax-ambiguity-2015.rs:17:50
|
--> $DIR/syntax-ambiguity-2015.rs:16:50
|
||||||
|
|
|
|
||||||
LL | while let Range { start: _, end: _ } = true..true && false { }
|
LL | while let Range { start: _, end: _ } = true..true && false { }
|
||||||
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
|
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
|
||||||
|
@ -26,7 +26,7 @@ LL | while let Range { start: _, end: _ } = true..true && false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `||`
|
error: ambiguous use of `||`
|
||||||
--> $DIR/syntax-ambiguity-2015.rs:20:50
|
--> $DIR/syntax-ambiguity-2015.rs:19:50
|
||||||
|
|
|
|
||||||
LL | while let Range { start: _, end: _ } = true..true || false { }
|
LL | while let Range { start: _, end: _ } = true..true || false { }
|
||||||
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
|
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
|
||||||
|
@ -35,7 +35,7 @@ LL | while let Range { start: _, end: _ } = true..true || false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `&&`
|
error: ambiguous use of `&&`
|
||||||
--> $DIR/syntax-ambiguity-2015.rs:23:19
|
--> $DIR/syntax-ambiguity-2015.rs:22:19
|
||||||
|
|
|
|
||||||
LL | if let true = false && false { }
|
LL | if let true = false && false { }
|
||||||
| ^^^^^^^^^^^^^^ help: consider adding parentheses: `(false && false)`
|
| ^^^^^^^^^^^^^^ help: consider adding parentheses: `(false && false)`
|
||||||
|
@ -44,7 +44,7 @@ LL | if let true = false && false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `&&`
|
error: ambiguous use of `&&`
|
||||||
--> $DIR/syntax-ambiguity-2015.rs:26:22
|
--> $DIR/syntax-ambiguity-2015.rs:25:22
|
||||||
|
|
|
|
||||||
LL | while let true = (1 == 2) && false { }
|
LL | while let true = (1 == 2) && false { }
|
||||||
| ^^^^^^^^^^^^^^^^^ help: consider adding parentheses: `((1 == 2) && false)`
|
| ^^^^^^^^^^^^^^^^^ help: consider adding parentheses: `((1 == 2) && false)`
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
// Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up
|
// Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up
|
||||||
// with examples easier.
|
// with examples easier.
|
||||||
#![feature(irrefutable_let_patterns)]
|
|
||||||
|
|
||||||
#[allow(irrefutable_let_patterns)]
|
#[allow(irrefutable_let_patterns)]
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: ambiguous use of `&&`
|
error: ambiguous use of `&&`
|
||||||
--> $DIR/syntax-ambiguity-2018.rs:11:47
|
--> $DIR/syntax-ambiguity-2018.rs:10:47
|
||||||
|
|
|
|
||||||
LL | if let Range { start: _, end: _ } = true..true && false { }
|
LL | if let Range { start: _, end: _ } = true..true && false { }
|
||||||
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
|
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
|
||||||
|
@ -8,7 +8,7 @@ LL | if let Range { start: _, end: _ } = true..true && false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `||`
|
error: ambiguous use of `||`
|
||||||
--> $DIR/syntax-ambiguity-2018.rs:14:47
|
--> $DIR/syntax-ambiguity-2018.rs:13:47
|
||||||
|
|
|
|
||||||
LL | if let Range { start: _, end: _ } = true..true || false { }
|
LL | if let Range { start: _, end: _ } = true..true || false { }
|
||||||
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
|
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
|
||||||
|
@ -17,7 +17,7 @@ LL | if let Range { start: _, end: _ } = true..true || false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `&&`
|
error: ambiguous use of `&&`
|
||||||
--> $DIR/syntax-ambiguity-2018.rs:17:50
|
--> $DIR/syntax-ambiguity-2018.rs:16:50
|
||||||
|
|
|
|
||||||
LL | while let Range { start: _, end: _ } = true..true && false { }
|
LL | while let Range { start: _, end: _ } = true..true && false { }
|
||||||
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
|
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)`
|
||||||
|
@ -26,7 +26,7 @@ LL | while let Range { start: _, end: _ } = true..true && false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `||`
|
error: ambiguous use of `||`
|
||||||
--> $DIR/syntax-ambiguity-2018.rs:20:50
|
--> $DIR/syntax-ambiguity-2018.rs:19:50
|
||||||
|
|
|
|
||||||
LL | while let Range { start: _, end: _ } = true..true || false { }
|
LL | while let Range { start: _, end: _ } = true..true || false { }
|
||||||
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
|
| ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)`
|
||||||
|
@ -35,7 +35,7 @@ LL | while let Range { start: _, end: _ } = true..true || false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `&&`
|
error: ambiguous use of `&&`
|
||||||
--> $DIR/syntax-ambiguity-2018.rs:23:19
|
--> $DIR/syntax-ambiguity-2018.rs:22:19
|
||||||
|
|
|
|
||||||
LL | if let true = false && false { }
|
LL | if let true = false && false { }
|
||||||
| ^^^^^^^^^^^^^^ help: consider adding parentheses: `(false && false)`
|
| ^^^^^^^^^^^^^^ help: consider adding parentheses: `(false && false)`
|
||||||
|
@ -44,7 +44,7 @@ LL | if let true = false && false { }
|
||||||
= note: see rust-lang/rust#53668 for more information
|
= note: see rust-lang/rust#53668 for more information
|
||||||
|
|
||||||
error: ambiguous use of `&&`
|
error: ambiguous use of `&&`
|
||||||
--> $DIR/syntax-ambiguity-2018.rs:26:22
|
--> $DIR/syntax-ambiguity-2018.rs:25:22
|
||||||
|
|
|
|
||||||
LL | while let true = (1 == 2) && false { }
|
LL | while let true = (1 == 2) && false { }
|
||||||
| ^^^^^^^^^^^^^^^^^ help: consider adding parentheses: `((1 == 2) && false)`
|
| ^^^^^^^^^^^^^^^^^ help: consider adding parentheses: `((1 == 2) && false)`
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
// should-fail-irrefutable_let_patterns
|
|
||||||
fn main() {
|
|
||||||
if let _ = 5 {}
|
|
||||||
//~^ ERROR irrefutable if-let pattern [E0162]
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
error[E0162]: irrefutable if-let pattern
|
|
||||||
--> $DIR/should-fail-no_gate_irrefutable_if_let_pattern.rs:3:12
|
|
||||||
|
|
|
||||||
LL | if let _ = 5 {}
|
|
||||||
| ^ irrefutable pattern
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0162`.
|
|
|
@ -1,7 +0,0 @@
|
||||||
#![feature(irrefutable_let_patterns)]
|
|
||||||
|
|
||||||
// should-fail-irrefutable_let_patterns_with_gate
|
|
||||||
fn main() {
|
|
||||||
if let _ = 5 {}
|
|
||||||
//~^ ERROR irrefutable if-let pattern [irrefutable_let_patterns]
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
error: irrefutable if-let pattern
|
|
||||||
--> $DIR/should-fail-with_gate_irrefutable_pattern_deny.rs:5:5
|
|
||||||
|
|
|
||||||
LL | if let _ = 5 {}
|
|
||||||
| ^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: #[deny(irrefutable_let_patterns)] on by default
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// run-pass
|
||||||
|
|
||||||
fn macros() {
|
fn macros() {
|
||||||
macro_rules! foo{
|
macro_rules! foo{
|
||||||
($p:pat, $e:expr, $b:block) => {{
|
($p:pat, $e:expr, $b:block) => {{
|
||||||
|
@ -10,16 +12,17 @@ fn macros() {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
foo!(a, 1, { //~ ERROR irrefutable while-let
|
foo!(a, 1, { //~ WARN irrefutable while-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
});
|
});
|
||||||
bar!(a, 1, { //~ ERROR irrefutable while-let
|
bar!(a, 1, { //~ WARN irrefutable while-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
while let a = 1 { //~ ERROR irrefutable while-let
|
while let a = 1 { //~ WARN irrefutable while-let
|
||||||
println!("irrefutable pattern");
|
println!("irrefutable pattern");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,32 @@
|
||||||
error[E0165]: irrefutable while-let pattern
|
warning: irrefutable while-let pattern
|
||||||
--> $DIR/while-let.rs:13:10
|
--> $DIR/while-let.rs:6:13
|
||||||
|
|
|
|
||||||
LL | foo!(a, 1, { //~ ERROR irrefutable while-let
|
LL | while let $p = $e $b
|
||||||
| ^ irrefutable pattern
|
| ^^^^^
|
||||||
|
...
|
||||||
error[E0165]: irrefutable while-let pattern
|
LL | / foo!(a, 1, { //~ WARN irrefutable while-let
|
||||||
--> $DIR/while-let.rs:16:10
|
LL | | println!("irrefutable pattern");
|
||||||
|
LL | | });
|
||||||
|
| |_______- in this macro invocation
|
||||||
|
|
|
|
||||||
LL | bar!(a, 1, { //~ ERROR irrefutable while-let
|
= note: #[warn(irrefutable_let_patterns)] on by default
|
||||||
| ^ irrefutable pattern
|
|
||||||
|
|
||||||
error[E0165]: irrefutable while-let pattern
|
warning: irrefutable while-let pattern
|
||||||
--> $DIR/while-let.rs:22:15
|
--> $DIR/while-let.rs:6:13
|
||||||
|
|
|
|
||||||
LL | while let a = 1 { //~ ERROR irrefutable while-let
|
LL | while let $p = $e $b
|
||||||
| ^ irrefutable pattern
|
| ^^^^^
|
||||||
|
...
|
||||||
|
LL | / bar!(a, 1, { //~ WARN irrefutable while-let
|
||||||
|
LL | | println!("irrefutable pattern");
|
||||||
|
LL | | });
|
||||||
|
| |_______- in this macro invocation
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
warning: irrefutable while-let pattern
|
||||||
|
--> $DIR/while-let.rs:24:5
|
||||||
|
|
|
||||||
|
LL | / while let a = 1 { //~ WARN irrefutable while-let
|
||||||
|
LL | | println!("irrefutable pattern");
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0165`.
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue