1
Fork 0

Implement partial error recovery for let with BinOpEq

When parsing `let x: i8 += 1` the compiler interprets `i8` as a trait
which makes it more complicated to do error recovery. More advanced
error recovery is not implemented in this commit.
This commit is contained in:
mibac138 2020-05-07 03:57:31 +02:00
parent f182c4af8a
commit d4fe9553f6
5 changed files with 72 additions and 2 deletions

View file

@ -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::{Applicability, PResult};
use rustc_errors::{struct_span_err, Applicability, PResult};
use rustc_span::source_map::{BytePos, Span};
use rustc_span::symbol::{kw, sym};
@ -217,7 +217,32 @@ impl<'a> Parser<'a> {
/// Parses the RHS of a local variable declaration (e.g., '= 14;').
fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option<P<Expr>>> {
if self.eat(&token::Eq) || skip_eq { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
let parse = if !self.eat(&token::Eq) && !skip_eq {
// Error recovery for `let x += 1`
if matches!(self.token.kind, TokenKind::BinOpEq(_)) {
struct_span_err!(
self.sess.span_diagnostic,
self.token.span,
E0067,
"can't reassign to a uninitialized variable"
)
.span_suggestion_short(
self.token.span,
"replace with `=` to initialize the variable",
"=".to_string(),
Applicability::MaybeIncorrect,
)
.emit();
self.bump();
true
} else {
false
}
} else {
true
};
if parse { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
}
/// Parses a block. No inner attributes are allowed.

View file

@ -0,0 +1,7 @@
#![allow(bare_trait_objects)]
fn main() {
let a: i8 += 1;
//~^ ERROR expected trait, found builtin type `i8`
let _ = a;
}

View file

@ -0,0 +1,9 @@
error[E0404]: expected trait, found builtin type `i8`
--> $DIR/let-binop-plus.rs:4:12
|
LL | let a: i8 += 1;
| ^^ not a trait
error: aborting due to previous error
For more information about this error, try `rustc --explain E0404`.

View file

@ -0,0 +1,8 @@
fn main() {
let a: i8 *= 1; //~ ERROR can't reassign to a uninitialized variable
let _ = a;
let b += 1; //~ ERROR can't reassign to a uninitialized variable
let _ = b;
let c *= 1; //~ ERROR can't reassign to a uninitialized variable
let _ = c;
}

View file

@ -0,0 +1,21 @@
error[E0067]: can't reassign to a uninitialized variable
--> $DIR/let-binop.rs:2:15
|
LL | let a: i8 *= 1;
| ^^ help: replace with `=` to initialize the variable
error[E0067]: can't reassign to a uninitialized variable
--> $DIR/let-binop.rs:4:11
|
LL | let b += 1;
| ^^ help: replace with `=` to initialize the variable
error[E0067]: can't reassign to a uninitialized variable
--> $DIR/let-binop.rs:6:11
|
LL | let c *= 1;
| ^^ help: replace with `=` to initialize the variable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0067`.