recover on 'mut', 'var', 'auto'

This commit is contained in:
Mazdak Farrokhzad 2019-12-03 18:08:19 +01:00
parent a0d20935cc
commit c9e1f13f6e
4 changed files with 120 additions and 3 deletions

View File

@ -14,7 +14,7 @@ use syntax::ast::{AttrVec, Attribute, AttrStyle, VisibilityKind, MacStmtStyle, M
use syntax::util::classify;
use syntax::token;
use syntax_pos::source_map::{respan, Span};
use syntax_pos::symbol::kw;
use syntax_pos::symbol::{kw, sym, Symbol};
use std::mem;
@ -39,8 +39,20 @@ impl<'a> Parser<'a> {
let lo = self.token.span;
if self.eat_keyword(kw::Let) {
let local = self.parse_local(attrs.into())?;
return Ok(Some(self.mk_stmt(lo.to(self.prev_span), StmtKind::Local(local))));
return self.parse_local_mk(lo, attrs.into()).map(Some)
}
if self.is_kw_followed_by_ident(kw::Mut) {
return self.recover_stmt_local(lo, attrs.into(), "missing `let`", "let mut");
}
if self.is_kw_followed_by_ident(kw::Auto) {
self.bump(); // `auto`
let msg = "to introduce a variable, write `let` instead of `auto`";
return self.recover_stmt_local(lo, attrs.into(), msg, "let");
}
if self.is_kw_followed_by_ident(sym::var) {
self.bump(); // `var`
let msg = "to introduce a variable, write `let` instead of `var`";
return self.recover_stmt_local(lo, attrs.into(), msg, "let");
}
let mac_vis = respan(lo, VisibilityKind::Inherited);
@ -189,6 +201,30 @@ impl<'a> Parser<'a> {
}
}
fn is_kw_followed_by_ident(&self, kw: Symbol) -> bool {
self.token.is_keyword(kw)
&& self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
}
fn recover_stmt_local(
&mut self,
span: Span,
attrs: AttrVec,
msg: &str,
sugg: &str,
) -> PResult<'a, Option<Stmt>> {
let stmt = self.parse_local_mk(span, attrs)?;
self.struct_span_err(stmt.span, "invalid variable declaration")
.span_suggestion_short(span, msg, sugg.to_string(), Applicability::MachineApplicable)
.emit();
Ok(Some(stmt))
}
fn parse_local_mk(&mut self, lo: Span, attrs: AttrVec) -> PResult<'a, Stmt> {
let local = self.parse_local(attrs.into())?;
Ok(self.mk_stmt(lo.to(self.prev_span), StmtKind::Local(local)))
}
/// Parses a local variable declaration.
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
let lo = self.prev_span;

View File

@ -773,6 +773,7 @@ symbols! {
usize,
v1,
val,
var,
vec,
Vec,
vis,

View File

@ -0,0 +1,21 @@
fn main() {
auto n = 0;//~ ERROR invalid variable declaration
//~^ HELP to introduce a variable, write `let` instead of `auto`
auto m;//~ ERROR invalid variable declaration
//~^ HELP to introduce a variable, write `let` instead of `auto`
m = 0;
var n = 0;//~ ERROR invalid variable declaration
//~^ HELP to introduce a variable, write `let` instead of `var`
var m;//~ ERROR invalid variable declaration
//~^ HELP to introduce a variable, write `let` instead of `var`
m = 0;
mut n = 0;//~ ERROR invalid variable declaration
//~^ HELP missing `let`
mut var;//~ ERROR invalid variable declaration
//~^ HELP missing `let`
var = 0;
let _recovery_witness: () = 0; //~ ERROR mismatched types
}

View File

@ -0,0 +1,59 @@
error: invalid variable declaration
--> $DIR/issue-65257-invalid-var-decl-recovery.rs:2:5
|
LL | auto n = 0;
| ----^^^^^^
| |
| help: to introduce a variable, write `let` instead of `auto`
error: invalid variable declaration
--> $DIR/issue-65257-invalid-var-decl-recovery.rs:4:5
|
LL | auto m;
| ----^^
| |
| help: to introduce a variable, write `let` instead of `auto`
error: invalid variable declaration
--> $DIR/issue-65257-invalid-var-decl-recovery.rs:8:5
|
LL | var n = 0;
| ---^^^^^^
| |
| help: to introduce a variable, write `let` instead of `var`
error: invalid variable declaration
--> $DIR/issue-65257-invalid-var-decl-recovery.rs:10:5
|
LL | var m;
| ---^^
| |
| help: to introduce a variable, write `let` instead of `var`
error: invalid variable declaration
--> $DIR/issue-65257-invalid-var-decl-recovery.rs:14:5
|
LL | mut n = 0;
| ---^^^^^^
| |
| help: missing `let`
error: invalid variable declaration
--> $DIR/issue-65257-invalid-var-decl-recovery.rs:16:5
|
LL | mut var;
| ---^^^^
| |
| help: missing `let`
error[E0308]: mismatched types
--> $DIR/issue-65257-invalid-var-decl-recovery.rs:20:33
|
LL | let _recovery_witness: () = 0;
| -- ^ expected `()`, found integer
| |
| expected due to this
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0308`.