Rollup merge of #75658 - tgnottingham:issue-75599, r=estebank

Don't emit "is not a logical operator" error outside of associative expressions

Avoid showing this error where it doesn't make sense by not assuming
"and" and "or" were intended to mean "&&" and "||" until after we decide
to continue parsing input as an associative expression.

Note that the decision of whether or not to continue parsing input as an
associative expression doesn't actually depend on this assumption.

Fixes #75599

---

First time contributor! Let me know if there are any conventions or policies I should be following that I missed here. Thanks :)
This commit is contained in:
Yuki Okushi 2020-08-19 15:54:35 +09:00 committed by GitHub
commit e6fe5232df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 42 additions and 170 deletions

View File

@ -308,7 +308,7 @@ impl<'a> Parser<'a> {
} }
fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool { fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool {
match (self.expr_is_complete(lhs), self.check_assoc_op().map(|op| op.node)) { match (self.expr_is_complete(lhs), AssocOp::from_token(&self.token)) {
// Semi-statement forms are odd: // Semi-statement forms are odd:
// See https://github.com/rust-lang/rust/issues/29071 // See https://github.com/rust-lang/rust/issues/29071
(true, None) => false, (true, None) => false,

View File

@ -5,10 +5,8 @@ fn test_and() {
let b = false; let b = false;
let _ = a and b; //~ ERROR `and` is not a logical operator let _ = a and b; //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
if a and b { //~ ERROR `and` is not a logical operator if a and b { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
@ -20,10 +18,8 @@ fn test_or() {
let b = false; let b = false;
let _ = a or b; //~ ERROR `or` is not a logical operator let _ = a or b; //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
if a or b { //~ ERROR `or` is not a logical operator if a or b { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -32,7 +28,6 @@ fn test_and_par() {
let a = true; let a = true;
let b = false; let b = false;
if (a and b) { //~ ERROR `and` is not a logical operator if (a and b) { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -41,7 +36,6 @@ fn test_or_par() {
let a = true; let a = true;
let b = false; let b = false;
if (a or b) { //~ ERROR `or` is not a logical operator if (a or b) { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -50,7 +44,6 @@ fn test_while_and() {
let a = true; let a = true;
let b = false; let b = false;
while a and b { //~ ERROR `and` is not a logical operator while a and b { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -59,7 +52,6 @@ fn test_while_or() {
let a = true; let a = true;
let b = false; let b = false;
while a or b { //~ ERROR `or` is not a logical operator while a or b { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }

View File

@ -7,23 +7,7 @@ LL | let _ = a and b;
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:7:15 --> $DIR/issue-54109-and_instead_of_ampersands.rs:9:10
|
LL | let _ = a and b;
| ^^^ help: use `&&` to perform logical conjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:10:10
|
LL | if a and b {
| ^^^ help: use `&&` to perform logical conjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:10:10
| |
LL | if a and b { LL | if a and b {
| ^^^ help: use `&&` to perform logical conjunction | ^^^ help: use `&&` to perform logical conjunction
@ -31,7 +15,7 @@ LL | if a and b {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15 --> $DIR/issue-54109-and_instead_of_ampersands.rs:20:15
| |
LL | let _ = a or b; LL | let _ = a or b;
| ^^ help: use `||` to perform logical disjunction | ^^ help: use `||` to perform logical disjunction
@ -39,23 +23,7 @@ LL | let _ = a or b;
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15 --> $DIR/issue-54109-and_instead_of_ampersands.rs:22:10
|
LL | let _ = a or b;
| ^^ help: use `||` to perform logical disjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:25:10
|
LL | if a or b {
| ^^ help: use `||` to perform logical disjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:25:10
| |
LL | if a or b { LL | if a or b {
| ^^ help: use `||` to perform logical disjunction | ^^ help: use `||` to perform logical disjunction
@ -63,15 +31,7 @@ LL | if a or b {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:34:11 --> $DIR/issue-54109-and_instead_of_ampersands.rs:30:11
|
LL | if (a and b) {
| ^^^ help: use `&&` to perform logical conjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:34:11
| |
LL | if (a and b) { LL | if (a and b) {
| ^^^ help: use `&&` to perform logical conjunction | ^^^ help: use `&&` to perform logical conjunction
@ -79,15 +39,7 @@ LL | if (a and b) {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:43:11 --> $DIR/issue-54109-and_instead_of_ampersands.rs:38:11
|
LL | if (a or b) {
| ^^ help: use `||` to perform logical disjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:43:11
| |
LL | if (a or b) { LL | if (a or b) {
| ^^ help: use `||` to perform logical disjunction | ^^ help: use `||` to perform logical disjunction
@ -95,15 +47,7 @@ LL | if (a or b) {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:52:13 --> $DIR/issue-54109-and_instead_of_ampersands.rs:46:13
|
LL | while a and b {
| ^^^ help: use `&&` to perform logical conjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:52:13
| |
LL | while a and b { LL | while a and b {
| ^^^ help: use `&&` to perform logical conjunction | ^^^ help: use `&&` to perform logical conjunction
@ -111,15 +55,7 @@ LL | while a and b {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:61:13 --> $DIR/issue-54109-and_instead_of_ampersands.rs:54:13
|
LL | while a or b {
| ^^ help: use `||` to perform logical disjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:61:13
| |
LL | while a or b { LL | while a or b {
| ^^ help: use `||` to perform logical disjunction | ^^ help: use `||` to perform logical disjunction
@ -127,13 +63,13 @@ LL | while a or b {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-54109-and_instead_of_ampersands.rs:15:33 --> $DIR/issue-54109-and_instead_of_ampersands.rs:13:33
| |
LL | let _recovery_witness: () = 0; LL | let _recovery_witness: () = 0;
| -- ^ expected `()`, found integer | -- ^ expected `()`, found integer
| | | |
| expected due to this | expected due to this
error: aborting due to 17 previous errors error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0308`. For more information about this error, try `rustc --explain E0308`.

View File

@ -11,10 +11,8 @@ fn test_and() {
let b = false; let b = false;
let _ = a && b; //~ ERROR `and` is not a logical operator let _ = a && b; //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
if a && b { //~ ERROR `and` is not a logical operator if a && b { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -24,10 +22,8 @@ fn test_or() {
let b = false; let b = false;
let _ = a || b; //~ ERROR `or` is not a logical operator let _ = a || b; //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
if a || b { //~ ERROR `or` is not a logical operator if a || b { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -36,7 +32,6 @@ fn test_and_par() {
let a = true; let a = true;
let b = false; let b = false;
if (a && b) { //~ ERROR `and` is not a logical operator if (a && b) { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -45,7 +40,6 @@ fn test_or_par() {
let a = true; let a = true;
let b = false; let b = false;
if (a || b) { //~ ERROR `or` is not a logical operator if (a || b) { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -54,7 +48,6 @@ fn test_while_and() {
let a = true; let a = true;
let b = false; let b = false;
while a && b { //~ ERROR `and` is not a logical operator while a && b { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -63,7 +56,6 @@ fn test_while_or() {
let a = true; let a = true;
let b = false; let b = false;
while a || b { //~ ERROR `or` is not a logical operator while a || b { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }

View File

@ -11,10 +11,8 @@ fn test_and() {
let b = false; let b = false;
let _ = a and b; //~ ERROR `and` is not a logical operator let _ = a and b; //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
if a and b { //~ ERROR `and` is not a logical operator if a and b { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -24,10 +22,8 @@ fn test_or() {
let b = false; let b = false;
let _ = a or b; //~ ERROR `or` is not a logical operator let _ = a or b; //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
if a or b { //~ ERROR `or` is not a logical operator if a or b { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -36,7 +32,6 @@ fn test_and_par() {
let a = true; let a = true;
let b = false; let b = false;
if (a and b) { //~ ERROR `and` is not a logical operator if (a and b) { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -45,7 +40,6 @@ fn test_or_par() {
let a = true; let a = true;
let b = false; let b = false;
if (a or b) { //~ ERROR `or` is not a logical operator if (a or b) { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -54,7 +48,6 @@ fn test_while_and() {
let a = true; let a = true;
let b = false; let b = false;
while a and b { //~ ERROR `and` is not a logical operator while a and b { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both"); println!("both");
} }
} }
@ -63,7 +56,6 @@ fn test_while_or() {
let a = true; let a = true;
let b = false; let b = false;
while a or b { //~ ERROR `or` is not a logical operator while a or b { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both"); println!("both");
} }
} }

View File

@ -7,23 +7,7 @@ LL | let _ = a and b;
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:13:15 --> $DIR/issue-54109-without-witness.rs:15:10
|
LL | let _ = a and b;
| ^^^ help: use `&&` to perform logical conjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:16:10
|
LL | if a and b {
| ^^^ help: use `&&` to perform logical conjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:16:10
| |
LL | if a and b { LL | if a and b {
| ^^^ help: use `&&` to perform logical conjunction | ^^^ help: use `&&` to perform logical conjunction
@ -31,7 +15,7 @@ LL | if a and b {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:26:15 --> $DIR/issue-54109-without-witness.rs:24:15
| |
LL | let _ = a or b; LL | let _ = a or b;
| ^^ help: use `||` to perform logical disjunction | ^^ help: use `||` to perform logical disjunction
@ -39,23 +23,7 @@ LL | let _ = a or b;
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:26:15 --> $DIR/issue-54109-without-witness.rs:26:10
|
LL | let _ = a or b;
| ^^ help: use `||` to perform logical disjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:29:10
|
LL | if a or b {
| ^^ help: use `||` to perform logical disjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:29:10
| |
LL | if a or b { LL | if a or b {
| ^^ help: use `||` to perform logical disjunction | ^^ help: use `||` to perform logical disjunction
@ -63,15 +31,7 @@ LL | if a or b {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:38:11 --> $DIR/issue-54109-without-witness.rs:34:11
|
LL | if (a and b) {
| ^^^ help: use `&&` to perform logical conjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:38:11
| |
LL | if (a and b) { LL | if (a and b) {
| ^^^ help: use `&&` to perform logical conjunction | ^^^ help: use `&&` to perform logical conjunction
@ -79,15 +39,7 @@ LL | if (a and b) {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:47:11 --> $DIR/issue-54109-without-witness.rs:42:11
|
LL | if (a or b) {
| ^^ help: use `||` to perform logical disjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:47:11
| |
LL | if (a or b) { LL | if (a or b) {
| ^^ help: use `||` to perform logical disjunction | ^^ help: use `||` to perform logical disjunction
@ -95,15 +47,7 @@ LL | if (a or b) {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:56:13 --> $DIR/issue-54109-without-witness.rs:50:13
|
LL | while a and b {
| ^^^ help: use `&&` to perform logical conjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:56:13
| |
LL | while a and b { LL | while a and b {
| ^^^ help: use `&&` to perform logical conjunction | ^^^ help: use `&&` to perform logical conjunction
@ -111,20 +55,12 @@ LL | while a and b {
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:65:13 --> $DIR/issue-54109-without-witness.rs:58:13
| |
LL | while a or b { LL | while a or b {
| ^^ help: use `||` to perform logical disjunction | ^^ help: use `||` to perform logical disjunction
| |
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: `or` is not a logical operator error: aborting due to 8 previous errors
--> $DIR/issue-54109-without-witness.rs:65:13
|
LL | while a or b {
| ^^ help: use `||` to perform logical disjunction
|
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
error: aborting due to 16 previous errors

View File

@ -0,0 +1,24 @@
// check-pass
#![allow(non_upper_case_globals)]
const or: usize = 1;
const and: usize = 2;
mod or {
pub const X: usize = 3;
}
mod and {
pub const X: usize = 4;
}
fn main() {
match 0 {
0 => {}
or => {}
and => {}
or::X => {}
and::X => {}
_ => {}
}
}