about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_parse/parser/stmt.rs24
-rw-r--r--src/test/ui/parser/let-binop.rs8
-rw-r--r--src/test/ui/parser/let-binop.stderr20
3 files changed, 50 insertions, 2 deletions
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index 849193151c3..53f32b7c800 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -216,8 +216,28 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the RHS of a local variable declaration (e.g., '= 14;').
-    fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option<P<Expr>>> {
-        if self.eat(&token::Eq) || skip_eq { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
+    fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>>> {
+        let eq_consumed = match self.token.kind {
+            token::BinOpEq(..) => {
+                // Recover `let x <op>= 1` as `let x = 1`
+                self.struct_span_err(
+                    self.token.span,
+                    "can't reassign to an uninitialized variable",
+                )
+                .span_suggestion_short(
+                    self.token.span,
+                    "initialize the variable",
+                    "=".to_string(),
+                    Applicability::MaybeIncorrect,
+                )
+                .emit();
+                self.bump();
+                true
+            }
+            _ => self.eat(&token::Eq),
+        };
+
+        Ok(if eq_consumed || eq_optional { Some(self.parse_expr()?) } else { None })
     }
 
     /// Parses a block. No inner attributes are allowed.
diff --git a/src/test/ui/parser/let-binop.rs b/src/test/ui/parser/let-binop.rs
new file mode 100644
index 00000000000..7f58f5df2d4
--- /dev/null
+++ b/src/test/ui/parser/let-binop.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let a: i8 *= 1; //~ ERROR can't reassign to an uninitialized variable
+    let _ = a;
+    let b += 1; //~ ERROR can't reassign to an uninitialized variable
+    let _ = b;
+    let c *= 1; //~ ERROR can't reassign to an uninitialized variable
+    let _ = c;
+}
diff --git a/src/test/ui/parser/let-binop.stderr b/src/test/ui/parser/let-binop.stderr
new file mode 100644
index 00000000000..71431499ac7
--- /dev/null
+++ b/src/test/ui/parser/let-binop.stderr
@@ -0,0 +1,20 @@
+error: can't reassign to an uninitialized variable
+  --> $DIR/let-binop.rs:2:15
+   |
+LL |     let a: i8 *= 1;
+   |               ^^ help: initialize the variable
+
+error: can't reassign to an uninitialized variable
+  --> $DIR/let-binop.rs:4:11
+   |
+LL |     let b += 1;
+   |           ^^ help: initialize the variable
+
+error: can't reassign to an uninitialized variable
+  --> $DIR/let-binop.rs:6:11
+   |
+LL |     let c *= 1;
+   |           ^^ help: initialize the variable
+
+error: aborting due to 3 previous errors
+