about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-08-08 21:17:15 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-08-10 11:44:09 -0700
commit308b5585f37ccc71d58f9afc43c573ce02b339d0 (patch)
treeec488ba62842173ea129ba5088257b1ec2803c07
parent18f3be7704a4ec7976fcd1272c728974243d29bd (diff)
downloadrust-308b5585f37ccc71d58f9afc43c573ce02b339d0.tar.gz
rust-308b5585f37ccc71d58f9afc43c573ce02b339d0.zip
Detect JS-style `===` and `!==` and recover
Fix #75312.
-rw-r--r--src/librustc_parse/parser/expr.rs23
-rw-r--r--src/test/ui/suggestions/js-style-comparison-op-separate-eq-token.rs5
-rw-r--r--src/test/ui/suggestions/js-style-comparison-op-separate-eq-token.stderr8
-rw-r--r--src/test/ui/suggestions/js-style-comparison-op.fixed8
-rw-r--r--src/test/ui/suggestions/js-style-comparison-op.rs8
-rw-r--r--src/test/ui/suggestions/js-style-comparison-op.stderr14
6 files changed, 66 insertions, 0 deletions
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 3aec300d86d..81e0c0382f8 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -195,6 +195,29 @@ impl<'a> Parser<'a> {
                     return Ok(expr);
                 }
             }
+
+            if (op.node == AssocOp::Equal || op.node == AssocOp::NotEqual)
+                && self.token.kind == token::Eq
+                && self.prev_token.span.hi() == self.token.span.lo()
+            {
+                // Look for JS' `===` and `!==` and recover 😇
+                let sp = op.span.to(self.token.span);
+                let sugg = match op.node {
+                    AssocOp::Equal => "==",
+                    AssocOp::NotEqual => "!=",
+                    _ => unreachable!(),
+                };
+                self.struct_span_err(sp, &format!("invalid comparison operator `{}=`", sugg))
+                    .span_suggestion_short(
+                        sp,
+                        &format!("`{s}=` is not a valid comparison operator, use `{s}`", s = sugg),
+                        sugg.to_string(),
+                        Applicability::MachineApplicable,
+                    )
+                    .emit();
+                self.bump();
+            }
+
             let op = op.node;
             // Special cases:
             if op == AssocOp::As {
diff --git a/src/test/ui/suggestions/js-style-comparison-op-separate-eq-token.rs b/src/test/ui/suggestions/js-style-comparison-op-separate-eq-token.rs
new file mode 100644
index 00000000000..b24d256481c
--- /dev/null
+++ b/src/test/ui/suggestions/js-style-comparison-op-separate-eq-token.rs
@@ -0,0 +1,5 @@
+fn main() {
+    if 1 == = 1 { //~ ERROR expected expression
+        println!("yup!");
+    }
+}
diff --git a/src/test/ui/suggestions/js-style-comparison-op-separate-eq-token.stderr b/src/test/ui/suggestions/js-style-comparison-op-separate-eq-token.stderr
new file mode 100644
index 00000000000..6adefe3de37
--- /dev/null
+++ b/src/test/ui/suggestions/js-style-comparison-op-separate-eq-token.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found `=`
+  --> $DIR/js-style-comparison-op-separate-eq-token.rs:2:13
+   |
+LL |     if 1 == = 1 {
+   |             ^ expected expression
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/js-style-comparison-op.fixed b/src/test/ui/suggestions/js-style-comparison-op.fixed
new file mode 100644
index 00000000000..f7e977b918d
--- /dev/null
+++ b/src/test/ui/suggestions/js-style-comparison-op.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+fn main() {
+    if 1 == 1 { //~ ERROR invalid comparison operator `===`
+        println!("yup!");
+    } else if 1 != 1 { //~ ERROR invalid comparison operator `!==`
+        println!("nope!");
+    }
+}
diff --git a/src/test/ui/suggestions/js-style-comparison-op.rs b/src/test/ui/suggestions/js-style-comparison-op.rs
new file mode 100644
index 00000000000..c89c1052ed9
--- /dev/null
+++ b/src/test/ui/suggestions/js-style-comparison-op.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+fn main() {
+    if 1 === 1 { //~ ERROR invalid comparison operator `===`
+        println!("yup!");
+    } else if 1 !== 1 { //~ ERROR invalid comparison operator `!==`
+        println!("nope!");
+    }
+}
diff --git a/src/test/ui/suggestions/js-style-comparison-op.stderr b/src/test/ui/suggestions/js-style-comparison-op.stderr
new file mode 100644
index 00000000000..33f7a0844fd
--- /dev/null
+++ b/src/test/ui/suggestions/js-style-comparison-op.stderr
@@ -0,0 +1,14 @@
+error: invalid comparison operator `===`
+  --> $DIR/js-style-comparison-op.rs:3:10
+   |
+LL |     if 1 === 1 {
+   |          ^^^ help: `===` is not a valid comparison operator, use `==`
+
+error: invalid comparison operator `!==`
+  --> $DIR/js-style-comparison-op.rs:5:17
+   |
+LL |     } else if 1 !== 1 {
+   |                 ^^^ help: `!==` is not a valid comparison operator, use `!=`
+
+error: aborting due to 2 previous errors
+