@@ -145,12 +145,12 @@ impl<'a> Parser<'a> {
145145 }
146146
147147 fn parse_local_mk ( & mut self , lo : Span , attrs : AttrVec ) -> PResult < ' a , Stmt > {
148- let local = self . parse_local ( attrs) ?;
148+ let local = self . parse_local ( lo , attrs) ?;
149149 Ok ( self . mk_stmt ( lo. to ( self . prev_token . span ) , StmtKind :: Local ( local) ) )
150150 }
151151
152152 /// Parses a local variable declaration.
153- fn parse_local ( & mut self , attrs : AttrVec ) -> PResult < ' a , P < Local > > {
153+ fn parse_local ( & mut self , let_span : Span , attrs : AttrVec ) -> PResult < ' a , P < Local > > {
154154 let lo = self . prev_token . span ;
155155 let pat = self . parse_top_pat ( GateOr :: Yes ) ?;
156156
@@ -174,7 +174,7 @@ impl<'a> Parser<'a> {
174174 } else {
175175 ( None , None )
176176 } ;
177- let init = match ( self . parse_initializer ( err. is_some ( ) ) , err) {
177+ let init = match ( self . parse_initializer ( let_span , ty . is_some ( ) , err. is_some ( ) ) , err) {
178178 ( Ok ( init) , None ) => {
179179 // init parsed, ty parsed
180180 init
@@ -216,23 +216,43 @@ impl<'a> Parser<'a> {
216216 }
217217
218218 /// Parses the RHS of a local variable declaration (e.g., '= 14;').
219- fn parse_initializer ( & mut self , skip_eq : bool ) -> PResult < ' a , Option < P < Expr > > > {
219+ fn parse_initializer (
220+ & mut self ,
221+ let_span : Span ,
222+ has_ty : bool ,
223+ skip_eq : bool ,
224+ ) -> PResult < ' a , Option < P < Expr > > > {
220225 let parse = if !self . eat ( & token:: Eq ) && !skip_eq {
221226 // Error recovery for `let x += 1`
222227 if matches ! ( self . token. kind, TokenKind :: BinOpEq ( _) ) {
223- struct_span_err ! (
228+ let mut err = struct_span_err ! (
224229 self . sess. span_diagnostic,
225230 self . token. span,
226231 E0067 ,
227232 "can't reassign to a uninitialized variable"
228- )
229- . span_suggestion_short (
233+ ) ;
234+ err . span_suggestion_short (
230235 self . token . span ,
231236 "replace with `=` to initialize the variable" ,
232237 "=" . to_string ( ) ,
233- Applicability :: MaybeIncorrect ,
234- )
235- . emit ( ) ;
238+ if has_ty {
239+ // for `let x: i8 += 1` it's highly likely that the `+` is a typo
240+ Applicability :: MachineApplicable
241+ } else {
242+ // for `let x += 1` it's a bit less likely that the `+` is a typo
243+ Applicability :: MaybeIncorrect
244+ } ,
245+ ) ;
246+ // In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
247+ if !has_ty {
248+ err. span_suggestion_short (
249+ let_span,
250+ "remove to reassign to a previously initialized variable" ,
251+ "" . to_string ( ) ,
252+ Applicability :: MaybeIncorrect ,
253+ ) ;
254+ }
255+ err. emit ( ) ;
236256 self . bump ( ) ;
237257 true
238258 } else {
0 commit comments