@@ -222,44 +222,43 @@ impl<'a> Parser<'a> {
222222 has_ty : bool ,
223223 skip_eq : bool ,
224224 ) -> PResult < ' a , Option < P < Expr > > > {
225- let parse = if !self . eat ( & token:: Eq ) && !skip_eq {
225+ // In case of code like `let x: i8 += 1`, `i8` is interpreted as a trait consuming the `+`
226+ // from `+=`.
227+ let ate_plus = self . prev_token . is_like_plus ( ) && has_ty;
228+ let parse = if !skip_eq && ( ate_plus || matches ! ( self . token. kind, TokenKind :: BinOpEq ( _) ) ) {
226229 // Error recovery for `let x += 1`
227- if matches ! ( self . token. kind, TokenKind :: BinOpEq ( _) ) {
228- let mut err = struct_span_err ! (
229- self . sess. span_diagnostic,
230- self . token. span,
231- E0067 ,
232- "can't reassign to a uninitialized variable"
233- ) ;
230+ let mut err = struct_span_err ! (
231+ self . sess. span_diagnostic,
232+ self . token. span,
233+ E0067 ,
234+ "can't reassign to a uninitialized variable"
235+ ) ;
236+ err. span_suggestion_short (
237+ self . token . span ,
238+ "replace with `=` to initialize the variable" ,
239+ "=" . to_string ( ) ,
240+ if has_ty {
241+ // for `let x: i8 += 1` it's highly likely that the `+` is a typo
242+ Applicability :: MachineApplicable
243+ } else {
244+ // for `let x += 1` it's a bit less likely that the `+` is a typo
245+ Applicability :: MaybeIncorrect
246+ } ,
247+ ) ;
248+ // In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
249+ if !has_ty {
234250 err. span_suggestion_short (
235- self . token . span ,
236- "replace with `=` to initialize the variable" ,
237- "=" . to_string ( ) ,
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- } ,
251+ let_span,
252+ "remove to reassign to a previously initialized variable" ,
253+ "" . to_string ( ) ,
254+ Applicability :: MaybeIncorrect ,
245255 ) ;
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 ( ) ;
256- self . bump ( ) ;
257- true
258- } else {
259- false
260256 }
261- } else {
257+ err. emit ( ) ;
258+ self . bump ( ) ;
262259 true
260+ } else {
261+ self . eat ( & token:: Eq ) || skip_eq
263262 } ;
264263
265264 if parse { Ok ( Some ( self . parse_expr ( ) ?) ) } else { Ok ( None ) }
0 commit comments