@@ -145,12 +145,12 @@ impl<'a> Parser<'a> {
145
145
}
146
146
147
147
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) ?;
149
149
Ok ( self . mk_stmt ( lo. to ( self . prev_token . span ) , StmtKind :: Local ( local) ) )
150
150
}
151
151
152
152
/// 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 > > {
154
154
let lo = self . prev_token . span ;
155
155
let pat = self . parse_top_pat ( GateOr :: Yes ) ?;
156
156
@@ -174,7 +174,7 @@ impl<'a> Parser<'a> {
174
174
} else {
175
175
( None , None )
176
176
} ;
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) {
178
178
( Ok ( init) , None ) => {
179
179
// init parsed, ty parsed
180
180
init
@@ -216,23 +216,43 @@ impl<'a> Parser<'a> {
216
216
}
217
217
218
218
/// 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 > > > {
220
225
let parse = if !self . eat ( & token:: Eq ) && !skip_eq {
221
226
// Error recovery for `let x += 1`
222
227
if matches ! ( self . token. kind, TokenKind :: BinOpEq ( _) ) {
223
- struct_span_err ! (
228
+ let mut err = struct_span_err ! (
224
229
self . sess. span_diagnostic,
225
230
self . token. span,
226
231
E0067 ,
227
232
"can't reassign to a uninitialized variable"
228
- )
229
- . span_suggestion_short (
233
+ ) ;
234
+ err . span_suggestion_short (
230
235
self . token . span ,
231
236
"replace with `=` to initialize the variable" ,
232
237
"=" . 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 ( ) ;
236
256
self . bump ( ) ;
237
257
true
238
258
} else {
0 commit comments