about summary refs log tree commit diff
path: root/src/librustc_parse
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-06-18 15:20:36 -0700
committerGitHub <noreply@github.com>2020-06-18 15:20:36 -0700
commit39f8784eb6056c21c120bfa93bbec73e19773727 (patch)
treef33d820ec959a1bd0152d5ee17cce6bd34712df4 /src/librustc_parse
parent45d033b21cdd009961860e62e1d1c785ecb2af41 (diff)
parent98532a30901d7544c49fe82f499db53699645de0 (diff)
downloadrust-39f8784eb6056c21c120bfa93bbec73e19773727.tar.gz
rust-39f8784eb6056c21c120bfa93bbec73e19773727.zip
Rollup merge of #71976 - mibac138:let-recovery, r=estebank
Improve diagnostics for `let x += 1`

Fixes(?) #66736

The code responsible for the `E0404` errors is [here](https://github.com/rust-lang/rust/blob/master/src/librustc_parse/parser/ty.rs#L399-L424) which I don't think can be easily modified to prevent emitting an error in one specific case. Because of this I couldn't get rid of `E0404` and instead added `E0067` along with a help message which will fix the problem.

r? @estebank
Diffstat (limited to 'src/librustc_parse')
-rw-r--r--src/librustc_parse/parser/stmt.rs24
1 files changed, 22 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.