about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2020-08-19 15:54:35 +0900
committerGitHub <noreply@github.com>2020-08-19 15:54:35 +0900
commite6fe5232df75246921f8b89d0161e4508f1cc535 (patch)
tree0c51d099c985a6fd00afc12599d7f850d992f553
parente6e917e12df1fc5b1866063ff8952a3b57b14fba (diff)
parentff73a409957d704aba735fb29ab4be2d77efe958 (diff)
downloadrust-e6fe5232df75246921f8b89d0161e4508f1cc535.tar.gz
rust-e6fe5232df75246921f8b89d0161e4508f1cc535.zip
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 :)
-rw-r--r--src/librustc_parse/parser/expr.rs2
-rw-r--r--src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs8
-rw-r--r--src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr82
-rw-r--r--src/test/ui/did_you_mean/issue-54109-without-witness.fixed8
-rw-r--r--src/test/ui/did_you_mean/issue-54109-without-witness.rs8
-rw-r--r--src/test/ui/did_you_mean/issue-54109-without-witness.stderr80
-rw-r--r--src/test/ui/issues/issue-75599.rs24
7 files changed, 42 insertions, 170 deletions
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index e5c28f225c6..62aec66a255 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -308,7 +308,7 @@ impl<'a> Parser<'a> {
     }
 
     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,
diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs
index 467daef63f6..44421b077fa 100644
--- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs
+++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs
@@ -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");
     }
 }
diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
index e8731cf238e..528c62f501e 100644
--- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
+++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
@@ -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,31 +31,15 @@ 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
+  --> $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) {
-   |           ^^^ help: use `&&` to perform logical conjunction
-   |
-   = 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,31 +47,15 @@ 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
+  --> $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 {
-   |             ^^^ help: use `&&` to perform logical conjunction
-   |
-   = 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`.
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.fixed b/src/test/ui/did_you_mean/issue-54109-without-witness.fixed
index 21471d75c82..5079a37f4da 100644
--- a/src/test/ui/did_you_mean/issue-54109-without-witness.fixed
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.fixed
@@ -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");
     }
 }
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.rs b/src/test/ui/did_you_mean/issue-54109-without-witness.rs
index bb9a3a19596..00660a938d5 100644
--- a/src/test/ui/did_you_mean/issue-54109-without-witness.rs
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.rs
@@ -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");
     }
 }
diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.stderr b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr
index fe48af592db..0350890c1fd 100644
--- a/src/test/ui/did_you_mean/issue-54109-without-witness.stderr
+++ b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr
@@ -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,31 +31,15 @@ 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
+  --> $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) {
-   |           ^^^ help: use `&&` to perform logical conjunction
-   |
-   = 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,36 +47,20 @@ 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
+  --> $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 {
-   |             ^^^ help: use `&&` to perform logical conjunction
-   |
-   = 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: `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: aborting due to 16 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/issues/issue-75599.rs b/src/test/ui/issues/issue-75599.rs
new file mode 100644
index 00000000000..0857676e4ed
--- /dev/null
+++ b/src/test/ui/issues/issue-75599.rs
@@ -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 => {}
+        _ => {}
+    }
+}