@@ -222,44 +222,43 @@ impl<'a> Parser<'a> {
222
222
has_ty : bool ,
223
223
skip_eq : bool ,
224
224
) -> 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 ( _) ) ) {
226
229
// 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 {
234
250
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 ,
245
255
) ;
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
260
256
}
261
- } else {
257
+ err. emit ( ) ;
258
+ self . bump ( ) ;
262
259
true
260
+ } else {
261
+ self . eat ( & token:: Eq ) || skip_eq
263
262
} ;
264
263
265
264
if parse { Ok ( Some ( self . parse_expr ( ) ?) ) } else { Ok ( None ) }
0 commit comments