Added warning/error for if-let-chain ambiguity.

With eRFC 2497, previously accepted ambigious syntax regarding use of
`&&` and `||` in if-let and while-let statements should now warn
or error depending on the edition.

This commit takes a naive approach to detecting ambigious use of `&&`
or `||` and will probably need fine tuned to handle all cases.
This commit is contained in:
David Wood 2018-08-31 15:59:42 +02:00
parent 685fb54317
commit 2ce56c5ebf
No known key found for this signature in database
GPG key ID: 01760B4F9F53F154
5 changed files with 250 additions and 0 deletions

View file

@ -0,0 +1,50 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// edition:2015
// compile-pass
// Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up
// with examples easier.
#![feature(irrefutable_let_patterns)]
#[allow(irrefutable_let_patterns)]
fn main() {
use std::ops::Range;
if let Range { start: _, end: _ } = true..true && false { }
//~^ WARN error in 2018
if let Range { start: _, end: _ } = true..true || false { }
//~^ WARN error in 2018
while let Range { start: _, end: _ } = true..true && false { }
//~^ WARN error in 2018
while let Range { start: _, end: _ } = true..true || false { }
//~^ WARN error in 2018
if let true = false && false { }
//~^ WARN error in 2018
while let true = (1 == 2) && false { }
//~^ WARN error in 2018
// The following cases are not an error as parenthesis are used to
// clarify intent:
if let Range { start: _, end: _ } = true..(true || false) { }
if let Range { start: _, end: _ } = true..(true && false) { }
while let Range { start: _, end: _ } = true..(true || false) { }
while let Range { start: _, end: _ } = true..(true && false) { }
}

View file

@ -0,0 +1,48 @@
warning: ambigious use of `&&`
--> $DIR/syntax-ambiguity-2015.rs:22:47
|
LL | if let Range { start: _, end: _ } = true..true && false { }
| ^^^^^^^^^^^^^ help: consider adding parenthesis: `(true && false)`
|
= note: This will be a error in Rust 2018 until the `let_chains` feature is stabilized.
warning: ambigious use of `||`
--> $DIR/syntax-ambiguity-2015.rs:25:47
|
LL | if let Range { start: _, end: _ } = true..true || false { }
| ^^^^^^^^^^^^^ help: consider adding parenthesis: `(true || false)`
|
= note: This will be a error in Rust 2018 until the `let_chains` feature is stabilized.
warning: ambigious use of `&&`
--> $DIR/syntax-ambiguity-2015.rs:28:50
|
LL | while let Range { start: _, end: _ } = true..true && false { }
| ^^^^^^^^^^^^^ help: consider adding parenthesis: `(true && false)`
|
= note: This will be a error in Rust 2018 until the `let_chains` feature is stabilized.
warning: ambigious use of `||`
--> $DIR/syntax-ambiguity-2015.rs:31:50
|
LL | while let Range { start: _, end: _ } = true..true || false { }
| ^^^^^^^^^^^^^ help: consider adding parenthesis: `(true || false)`
|
= note: This will be a error in Rust 2018 until the `let_chains` feature is stabilized.
warning: ambigious use of `&&`
--> $DIR/syntax-ambiguity-2015.rs:34:19
|
LL | if let true = false && false { }
| ^^^^^^^^^^^^^^ help: consider adding parenthesis: `(false && false)`
|
= note: This will be a error in Rust 2018 until the `let_chains` feature is stabilized.
warning: ambigious use of `&&`
--> $DIR/syntax-ambiguity-2015.rs:37:22
|
LL | while let true = (1 == 2) && false { }
| ^^^^^^^^^^^^^^^^^ help: consider adding parenthesis: `((1 == 2) && false)`
|
= note: This will be a error in Rust 2018 until the `let_chains` feature is stabilized.

View file

@ -0,0 +1,49 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// edition:2018
// Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up
// with examples easier.
#![feature(irrefutable_let_patterns)]
#[allow(irrefutable_let_patterns)]
fn main() {
use std::ops::Range;
if let Range { start: _, end: _ } = true..true && false { }
//~^ ERROR ambigious use of `&&`
if let Range { start: _, end: _ } = true..true || false { }
//~^ ERROR ambigious use of `||`
while let Range { start: _, end: _ } = true..true && false { }
//~^ ERROR ambigious use of `&&`
while let Range { start: _, end: _ } = true..true || false { }
//~^ ERROR ambigious use of `||`
if let true = false && false { }
//~^ ERROR ambigious use of `&&`
while let true = (1 == 2) && false { }
//~^ ERROR ambigious use of `&&`
// The following cases are not an error as parenthesis are used to
// clarify intent:
if let Range { start: _, end: _ } = true..(true || false) { }
if let Range { start: _, end: _ } = true..(true && false) { }
while let Range { start: _, end: _ } = true..(true || false) { }
while let Range { start: _, end: _ } = true..(true && false) { }
}

View file

@ -0,0 +1,50 @@
error: ambigious use of `&&`
--> $DIR/syntax-ambiguity-2018.rs:21:47
|
LL | if let Range { start: _, end: _ } = true..true && false { }
| ^^^^^^^^^^^^^ help: consider adding parenthesis: `(true && false)`
|
= note: This will be a error until the `let_chains` feature is stabilized.
error: ambigious use of `||`
--> $DIR/syntax-ambiguity-2018.rs:24:47
|
LL | if let Range { start: _, end: _ } = true..true || false { }
| ^^^^^^^^^^^^^ help: consider adding parenthesis: `(true || false)`
|
= note: This will be a error until the `let_chains` feature is stabilized.
error: ambigious use of `&&`
--> $DIR/syntax-ambiguity-2018.rs:27:50
|
LL | while let Range { start: _, end: _ } = true..true && false { }
| ^^^^^^^^^^^^^ help: consider adding parenthesis: `(true && false)`
|
= note: This will be a error until the `let_chains` feature is stabilized.
error: ambigious use of `||`
--> $DIR/syntax-ambiguity-2018.rs:30:50
|
LL | while let Range { start: _, end: _ } = true..true || false { }
| ^^^^^^^^^^^^^ help: consider adding parenthesis: `(true || false)`
|
= note: This will be a error until the `let_chains` feature is stabilized.
error: ambigious use of `&&`
--> $DIR/syntax-ambiguity-2018.rs:33:19
|
LL | if let true = false && false { }
| ^^^^^^^^^^^^^^ help: consider adding parenthesis: `(false && false)`
|
= note: This will be a error until the `let_chains` feature is stabilized.
error: ambigious use of `&&`
--> $DIR/syntax-ambiguity-2018.rs:36:22
|
LL | while let true = (1 == 2) && false { }
| ^^^^^^^^^^^^^^^^^ help: consider adding parenthesis: `((1 == 2) && false)`
|
= note: This will be a error until the `let_chains` feature is stabilized.
error: aborting due to 6 previous errors