Skip to content

Commit

Permalink
Adjust according to petrochenkov's review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
mibac138 committed May 21, 2020
1 parent 6ad24ba commit 98532a3
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 91 deletions.
65 changes: 22 additions & 43 deletions src/librustc_parse/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_ast::ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKin
use rustc_ast::ptr::P;
use rustc_ast::token::{self, TokenKind};
use rustc_ast::util::classify;
use rustc_errors::{struct_span_err, Applicability, PResult};
use rustc_errors::{Applicability, PResult};
use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym};

Expand Down Expand Up @@ -145,12 +145,12 @@ impl<'a> Parser<'a> {
}

fn parse_local_mk(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, Stmt> {
let local = self.parse_local(lo, attrs)?;
let local = self.parse_local(attrs)?;
Ok(self.mk_stmt(lo.to(self.prev_token.span), StmtKind::Local(local)))
}

/// Parses a local variable declaration.
fn parse_local(&mut self, let_span: Span, attrs: AttrVec) -> PResult<'a, P<Local>> {
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
let lo = self.prev_token.span;
let pat = self.parse_top_pat(GateOr::Yes)?;

Expand All @@ -174,10 +174,7 @@ impl<'a> Parser<'a> {
} else {
(None, None)
};
let init = match (
self.parse_initializer(let_span.until(pat.span), ty.is_some(), err.is_some()),
err,
) {
let init = match (self.parse_initializer(err.is_some()), err) {
(Ok(init), None) => {
// init parsed, ty parsed
init
Expand Down Expand Up @@ -219,46 +216,28 @@ impl<'a> Parser<'a> {
}

/// Parses the RHS of a local variable declaration (e.g., '= 14;').
fn parse_initializer(
&mut self,
let_span: Span,
has_ty: bool,
skip_eq: bool,
) -> PResult<'a, Option<P<Expr>>> {
// In case of code like `let x: i8 += 1`, `i8` is interpreted as a trait consuming the `+`
// from `+=`.
let ate_plus = self.prev_token.is_like_plus() && has_ty;
let parse = if !skip_eq && (ate_plus || matches!(self.token.kind, TokenKind::BinOpEq(_))) {
// Error recovery for `let x += 1`
let mut err = struct_span_err!(
self.sess.span_diagnostic,
self.token.span,
E0067,
"can't reassign to an uninitialized variable"
);
err.span_suggestion_short(
self.token.span,
"initialize the variable",
"=".to_string(),
Applicability::MaybeIncorrect,
);
// In case of code like `let x += 1` it's possible the user may have meant to write `x += 1`
if !has_ty {
err.span_suggestion_short(
let_span,
"otherwise, reassign to a previously initialized variable",
"".to_string(),
fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>>> {
let eq_consumed = match self.token.kind {
token::BinOpEq(..) => {
// Recover `let x <op>= 1` as `let x = 1`
self.struct_span_err(
self.token.span,
"can't reassign to an uninitialized variable",
)
.span_suggestion_short(
self.token.span,
"initialize the variable",
"=".to_string(),
Applicability::MaybeIncorrect,
);
)
.emit();
self.bump();
true
}
err.emit();
self.bump();
true
} else {
self.eat(&token::Eq) || skip_eq
_ => self.eat(&token::Eq),
};

if parse { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
Ok(if eq_consumed || eq_optional { Some(self.parse_expr()?) } else { None })
}

/// Parses a block. No inner attributes are allowed.
Expand Down
8 changes: 0 additions & 8 deletions src/test/ui/parser/let-binop-plus.rs

This file was deleted.

16 changes: 0 additions & 16 deletions src/test/ui/parser/let-binop-plus.stderr

This file was deleted.

29 changes: 5 additions & 24 deletions src/test/ui/parser/let-binop.stderr
Original file line number Diff line number Diff line change
@@ -1,39 +1,20 @@
error[E0067]: can't reassign to an uninitialized variable
error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:2:15
|
LL | let a: i8 *= 1;
| ^^ help: initialize the variable

error[E0067]: can't reassign to an uninitialized variable
error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:4:11
|
LL | let b += 1;
| ^^
|
help: initialize the variable
|
LL | let b = 1;
| ^
help: otherwise, reassign to a previously initialized variable
|
LL | b += 1;
| --
| ^^ help: initialize the variable

error[E0067]: can't reassign to an uninitialized variable
error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:6:11
|
LL | let c *= 1;
| ^^
|
help: initialize the variable
|
LL | let c = 1;
| ^
help: otherwise, reassign to a previously initialized variable
|
LL | c *= 1;
| --
| ^^ help: initialize the variable

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0067`.

0 comments on commit 98532a3

Please sign in to comment.