@@ -12,7 +12,7 @@ use rustc_ast::ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKin
12
12
use rustc_ast:: ptr:: P ;
13
13
use rustc_ast:: token:: { self , TokenKind } ;
14
14
use rustc_ast:: util:: classify;
15
- use rustc_errors:: { struct_span_err , Applicability , PResult } ;
15
+ use rustc_errors:: { Applicability , PResult } ;
16
16
use rustc_span:: source_map:: { BytePos , Span } ;
17
17
use rustc_span:: symbol:: { kw, sym} ;
18
18
@@ -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 ( lo , attrs) ?;
148
+ let local = self . parse_local ( 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 , let_span : Span , attrs : AttrVec ) -> PResult < ' a , P < Local > > {
153
+ fn parse_local ( & mut self , 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,10 +174,7 @@ impl<'a> Parser<'a> {
174
174
} else {
175
175
( None , None )
176
176
} ;
177
- let init = match (
178
- self . parse_initializer ( let_span. until ( pat. span ) , ty. is_some ( ) , err. is_some ( ) ) ,
179
- err,
180
- ) {
177
+ let init = match ( self . parse_initializer ( err. is_some ( ) ) , err) {
181
178
( Ok ( init) , None ) => {
182
179
// init parsed, ty parsed
183
180
init
@@ -219,46 +216,28 @@ impl<'a> Parser<'a> {
219
216
}
220
217
221
218
/// Parses the RHS of a local variable declaration (e.g., '= 14;').
222
- fn parse_initializer (
223
- & mut self ,
224
- let_span : Span ,
225
- has_ty : bool ,
226
- skip_eq : bool ,
227
- ) -> PResult < ' a , Option < P < Expr > > > {
228
- // In case of code like `let x: i8 += 1`, `i8` is interpreted as a trait consuming the `+`
229
- // from `+=`.
230
- let ate_plus = self . prev_token . is_like_plus ( ) && has_ty;
231
- let parse = if !skip_eq && ( ate_plus || matches ! ( self . token. kind, TokenKind :: BinOpEq ( _) ) ) {
232
- // Error recovery for `let x += 1`
233
- let mut err = struct_span_err ! (
234
- self . sess. span_diagnostic,
235
- self . token. span,
236
- E0067 ,
237
- "can't reassign to an uninitialized variable"
238
- ) ;
239
- err. span_suggestion_short (
240
- self . token . span ,
241
- "initialize the variable" ,
242
- "=" . to_string ( ) ,
243
- Applicability :: MaybeIncorrect ,
244
- ) ;
245
- // In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
246
- if !has_ty {
247
- err. span_suggestion_short (
248
- let_span,
249
- "otherwise, reassign to a previously initialized variable" ,
250
- "" . to_string ( ) ,
219
+ fn parse_initializer ( & mut self , eq_optional : bool ) -> PResult < ' a , Option < P < Expr > > > {
220
+ let eq_consumed = match self . token . kind {
221
+ token:: BinOpEq ( ..) => {
222
+ // Recover `let x <op>= 1` as `let x = 1`
223
+ self . struct_span_err (
224
+ self . token . span ,
225
+ "can't reassign to an uninitialized variable" ,
226
+ )
227
+ . span_suggestion_short (
228
+ self . token . span ,
229
+ "initialize the variable" ,
230
+ "=" . to_string ( ) ,
251
231
Applicability :: MaybeIncorrect ,
252
- ) ;
232
+ )
233
+ . emit ( ) ;
234
+ self . bump ( ) ;
235
+ true
253
236
}
254
- err. emit ( ) ;
255
- self . bump ( ) ;
256
- true
257
- } else {
258
- self . eat ( & token:: Eq ) || skip_eq
237
+ _ => self . eat ( & token:: Eq ) ,
259
238
} ;
260
239
261
- if parse { Ok ( Some ( self . parse_expr ( ) ?) ) } else { Ok ( None ) }
240
+ Ok ( if eq_consumed || eq_optional { Some ( self . parse_expr ( ) ?) } else { None } )
262
241
}
263
242
264
243
/// Parses a block. No inner attributes are allowed.
0 commit comments