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 @@ pub(super) fn parse_assoc_expr_with(
}
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:
// See https://github.com/rust-lang/rust/issues/29071
(true, None) => false,

View File

@ -5,10 +5,8 @@ fn test_and() {
let b = false;
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
//~| ERROR `and` is not a logical operator
println!("both");
}
@ -20,10 +18,8 @@ fn test_or() {
let b = false;
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
//~| ERROR `or` is not a logical operator
println!("both");
}
}
@ -32,7 +28,6 @@ fn test_and_par() {
let a = true;
let b = false;
if (a and b) { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both");
}
}
@ -41,7 +36,6 @@ fn test_or_par() {
let a = true;
let b = false;
if (a or b) { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both");
}
}
@ -50,7 +44,6 @@ fn test_while_and() {
let a = true;
let b = false;
while a and b { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both");
}
}
@ -59,7 +52,6 @@ fn test_while_or() {
let a = true;
let b = false;
while a or b { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
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
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:7:15
|
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
--> $DIR/issue-54109-and_instead_of_ampersands.rs:9:10
|
LL | if a and b {
| ^^^ 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
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;
| ^^ 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
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:15
|
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
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:10
|
LL | if a or b {
| ^^ 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
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.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-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
@ -79,15 +39,7 @@ LL | if (a and b) {
= 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) {
| ^^ 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
--> $DIR/issue-54109-and_instead_of_ampersands.rs:38:11
|
LL | if (a or b) {
| ^^ 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
error: `and` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:52: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
--> $DIR/issue-54109-and_instead_of_ampersands.rs:46:13
|
LL | while a and b {
| ^^^ 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
error: `or` is not a logical operator
--> $DIR/issue-54109-and_instead_of_ampersands.rs:61: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
--> $DIR/issue-54109-and_instead_of_ampersands.rs:54:13
|
LL | while a or b {
| ^^ 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
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;
| -- ^ expected `()`, found integer
| |
| 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`.

View File

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

View File

@ -11,10 +11,8 @@ fn test_and() {
let b = false;
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
//~| ERROR `and` is not a logical operator
println!("both");
}
}
@ -24,10 +22,8 @@ fn test_or() {
let b = false;
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
//~| ERROR `or` is not a logical operator
println!("both");
}
}
@ -36,7 +32,6 @@ fn test_and_par() {
let a = true;
let b = false;
if (a and b) { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both");
}
}
@ -45,7 +40,6 @@ fn test_or_par() {
let a = true;
let b = false;
if (a or b) { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
println!("both");
}
}
@ -54,7 +48,6 @@ fn test_while_and() {
let a = true;
let b = false;
while a and b { //~ ERROR `and` is not a logical operator
//~| ERROR `and` is not a logical operator
println!("both");
}
}
@ -63,7 +56,6 @@ fn test_while_or() {
let a = true;
let b = false;
while a or b { //~ ERROR `or` is not a logical operator
//~| ERROR `or` is not a logical operator
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
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:13:15
|
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
--> $DIR/issue-54109-without-witness.rs:15:10
|
LL | if a and b {
| ^^^ 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
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;
| ^^ 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
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:26:15
|
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
--> $DIR/issue-54109-without-witness.rs:26:10
|
LL | if a or b {
| ^^ 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
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:38: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
--> $DIR/issue-54109-without-witness.rs:34:11
|
LL | if (a and b) {
| ^^^ 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
error: `or` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:47: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
--> $DIR/issue-54109-without-witness.rs:42:11
|
LL | if (a or b) {
| ^^ 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
error: `and` is not a logical operator
--> $DIR/issue-54109-without-witness.rs:56: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
--> $DIR/issue-54109-without-witness.rs:50:13
|
LL | while a and b {
| ^^^ 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
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 {
| ^^ 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: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
error: aborting due to 8 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 => {}
_ => {}
}
}