Migrate "invalid variable declaration" errors to SessionDiagnostic
This commit is contained in:
parent
86c6ebee8f
commit
e8499cfadc
3 changed files with 50 additions and 19 deletions
|
@ -32,3 +32,12 @@ parser_incorrect_use_of_await =
|
||||||
parser_in_in_typo =
|
parser_in_in_typo =
|
||||||
expected iterable, found keyword `in`
|
expected iterable, found keyword `in`
|
||||||
.suggestion = remove the duplicated `in`
|
.suggestion = remove the duplicated `in`
|
||||||
|
|
||||||
|
parser_invalid_variable_declaration =
|
||||||
|
invalid variable declaration
|
||||||
|
|
||||||
|
parser_switch_mut_let_order =
|
||||||
|
switch the order of `mut` and `let`
|
||||||
|
parser_missing_let_before_mut = missing keyword
|
||||||
|
parser_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
|
||||||
|
parser_use_let_not_var = write `let` instead of `var` to introduce a new variable
|
||||||
|
|
|
@ -334,6 +334,35 @@ struct InInTypo {
|
||||||
sugg_span: Span,
|
sugg_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(SessionDiagnostic)]
|
||||||
|
#[error(parser::invalid_variable_declaration)]
|
||||||
|
pub struct InvalidVariableDeclaration {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
#[subdiagnostic]
|
||||||
|
pub sub: InvalidVariableDeclarationSub,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SessionSubdiagnostic)]
|
||||||
|
pub enum InvalidVariableDeclarationSub {
|
||||||
|
#[suggestion(
|
||||||
|
parser::switch_mut_let_order,
|
||||||
|
applicability = "maybe-incorrect",
|
||||||
|
code = "let mut"
|
||||||
|
)]
|
||||||
|
SwitchMutLetOrder(#[primary_span] Span),
|
||||||
|
#[suggestion(
|
||||||
|
parser::missing_let_before_mut,
|
||||||
|
applicability = "machine-applicable",
|
||||||
|
code = "let mut"
|
||||||
|
)]
|
||||||
|
MissingLet(#[primary_span] Span),
|
||||||
|
#[suggestion(parser::use_let_not_auto, applicability = "machine-applicable", code = "let")]
|
||||||
|
UseLetNotAuto(#[primary_span] Span),
|
||||||
|
#[suggestion(parser::use_let_not_var, applicability = "machine-applicable", code = "let")]
|
||||||
|
UseLetNotVar(#[primary_span] Span),
|
||||||
|
}
|
||||||
|
|
||||||
// SnapshotParser is used to create a snapshot of the parser
|
// SnapshotParser is used to create a snapshot of the parser
|
||||||
// without causing duplicate errors being emitted when the `Parser`
|
// without causing duplicate errors being emitted when the `Parser`
|
||||||
// is dropped.
|
// is dropped.
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
|
use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
|
||||||
use super::diagnostics::{AttemptLocalParseRecovery, Error};
|
use super::diagnostics::{
|
||||||
|
AttemptLocalParseRecovery, Error, InvalidVariableDeclaration, InvalidVariableDeclarationSub,
|
||||||
|
};
|
||||||
use super::expr::LhsExpr;
|
use super::expr::LhsExpr;
|
||||||
use super::pat::RecoverComma;
|
use super::pat::RecoverComma;
|
||||||
use super::path::PathStyle;
|
use super::path::PathStyle;
|
||||||
|
@ -58,28 +60,22 @@ impl<'a> Parser<'a> {
|
||||||
if self.token.is_keyword(kw::Mut) && self.is_keyword_ahead(1, &[kw::Let]) {
|
if self.token.is_keyword(kw::Mut) && self.is_keyword_ahead(1, &[kw::Let]) {
|
||||||
self.bump();
|
self.bump();
|
||||||
let mut_let_span = lo.to(self.token.span);
|
let mut_let_span = lo.to(self.token.span);
|
||||||
self.struct_span_err(mut_let_span, "invalid variable declaration")
|
self.sess.emit_err(InvalidVariableDeclaration {
|
||||||
.span_suggestion(
|
span: mut_let_span,
|
||||||
mut_let_span,
|
sub: InvalidVariableDeclarationSub::SwitchMutLetOrder(mut_let_span),
|
||||||
"switch the order of `mut` and `let`",
|
});
|
||||||
"let mut",
|
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
)
|
|
||||||
.emit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Some(if self.token.is_keyword(kw::Let) {
|
Ok(Some(if self.token.is_keyword(kw::Let) {
|
||||||
self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
|
self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
|
||||||
} else if self.is_kw_followed_by_ident(kw::Mut) {
|
} else if self.is_kw_followed_by_ident(kw::Mut) {
|
||||||
self.recover_stmt_local(lo, attrs, "missing keyword", "let mut")?
|
self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::MissingLet)?
|
||||||
} else if self.is_kw_followed_by_ident(kw::Auto) {
|
} else if self.is_kw_followed_by_ident(kw::Auto) {
|
||||||
self.bump(); // `auto`
|
self.bump(); // `auto`
|
||||||
let msg = "write `let` instead of `auto` to introduce a new variable";
|
self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto)?
|
||||||
self.recover_stmt_local(lo, attrs, msg, "let")?
|
|
||||||
} else if self.is_kw_followed_by_ident(sym::var) {
|
} else if self.is_kw_followed_by_ident(sym::var) {
|
||||||
self.bump(); // `var`
|
self.bump(); // `var`
|
||||||
let msg = "write `let` instead of `var` to introduce a new variable";
|
self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar)?
|
||||||
self.recover_stmt_local(lo, attrs, msg, "let")?
|
|
||||||
} else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
|
} else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
|
||||||
// We have avoided contextual keywords like `union`, items with `crate` visibility,
|
// We have avoided contextual keywords like `union`, items with `crate` visibility,
|
||||||
// or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
|
// or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
|
||||||
|
@ -217,13 +213,10 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
lo: Span,
|
lo: Span,
|
||||||
attrs: AttrWrapper,
|
attrs: AttrWrapper,
|
||||||
msg: &str,
|
subdiagnostic: fn(Span) -> InvalidVariableDeclarationSub,
|
||||||
sugg: &str,
|
|
||||||
) -> PResult<'a, Stmt> {
|
) -> PResult<'a, Stmt> {
|
||||||
let stmt = self.recover_local_after_let(lo, attrs)?;
|
let stmt = self.recover_local_after_let(lo, attrs)?;
|
||||||
self.struct_span_err(lo, "invalid variable declaration")
|
self.sess.emit_err(InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) });
|
||||||
.span_suggestion(lo, msg, sugg, Applicability::MachineApplicable)
|
|
||||||
.emit();
|
|
||||||
Ok(stmt)
|
Ok(stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue