Skip to content

Commit e8499cf

Browse files
committed
Migrate "invalid variable declaration" errors to SessionDiagnostic
1 parent 86c6ebe commit e8499cf

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

compiler/rustc_error_messages/locales/en-US/parser.ftl

+9
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,12 @@ parser_incorrect_use_of_await =
3232
parser_in_in_typo =
3333
expected iterable, found keyword `in`
3434
.suggestion = remove the duplicated `in`
35+
36+
parser_invalid_variable_declaration =
37+
invalid variable declaration
38+
39+
parser_switch_mut_let_order =
40+
switch the order of `mut` and `let`
41+
parser_missing_let_before_mut = missing keyword
42+
parser_use_let_not_auto = write `let` instead of `auto` to introduce a new variable
43+
parser_use_let_not_var = write `let` instead of `var` to introduce a new variable

compiler/rustc_parse/src/parser/diagnostics.rs

+29
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,35 @@ struct InInTypo {
334334
sugg_span: Span,
335335
}
336336

337+
#[derive(SessionDiagnostic)]
338+
#[error(parser::invalid_variable_declaration)]
339+
pub struct InvalidVariableDeclaration {
340+
#[primary_span]
341+
pub span: Span,
342+
#[subdiagnostic]
343+
pub sub: InvalidVariableDeclarationSub,
344+
}
345+
346+
#[derive(SessionSubdiagnostic)]
347+
pub enum InvalidVariableDeclarationSub {
348+
#[suggestion(
349+
parser::switch_mut_let_order,
350+
applicability = "maybe-incorrect",
351+
code = "let mut"
352+
)]
353+
SwitchMutLetOrder(#[primary_span] Span),
354+
#[suggestion(
355+
parser::missing_let_before_mut,
356+
applicability = "machine-applicable",
357+
code = "let mut"
358+
)]
359+
MissingLet(#[primary_span] Span),
360+
#[suggestion(parser::use_let_not_auto, applicability = "machine-applicable", code = "let")]
361+
UseLetNotAuto(#[primary_span] Span),
362+
#[suggestion(parser::use_let_not_var, applicability = "machine-applicable", code = "let")]
363+
UseLetNotVar(#[primary_span] Span),
364+
}
365+
337366
// SnapshotParser is used to create a snapshot of the parser
338367
// without causing duplicate errors being emitted when the `Parser`
339368
// is dropped.

compiler/rustc_parse/src/parser/stmt.rs

+12-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
2-
use super::diagnostics::{AttemptLocalParseRecovery, Error};
2+
use super::diagnostics::{
3+
AttemptLocalParseRecovery, Error, InvalidVariableDeclaration, InvalidVariableDeclarationSub,
4+
};
35
use super::expr::LhsExpr;
46
use super::pat::RecoverComma;
57
use super::path::PathStyle;
@@ -58,28 +60,22 @@ impl<'a> Parser<'a> {
5860
if self.token.is_keyword(kw::Mut) && self.is_keyword_ahead(1, &[kw::Let]) {
5961
self.bump();
6062
let mut_let_span = lo.to(self.token.span);
61-
self.struct_span_err(mut_let_span, "invalid variable declaration")
62-
.span_suggestion(
63-
mut_let_span,
64-
"switch the order of `mut` and `let`",
65-
"let mut",
66-
Applicability::MaybeIncorrect,
67-
)
68-
.emit();
63+
self.sess.emit_err(InvalidVariableDeclaration {
64+
span: mut_let_span,
65+
sub: InvalidVariableDeclarationSub::SwitchMutLetOrder(mut_let_span),
66+
});
6967
}
7068

7169
Ok(Some(if self.token.is_keyword(kw::Let) {
7270
self.parse_local_mk(lo, attrs, capture_semi, force_collect)?
7371
} else if self.is_kw_followed_by_ident(kw::Mut) {
74-
self.recover_stmt_local(lo, attrs, "missing keyword", "let mut")?
72+
self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::MissingLet)?
7573
} else if self.is_kw_followed_by_ident(kw::Auto) {
7674
self.bump(); // `auto`
77-
let msg = "write `let` instead of `auto` to introduce a new variable";
78-
self.recover_stmt_local(lo, attrs, msg, "let")?
75+
self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotAuto)?
7976
} else if self.is_kw_followed_by_ident(sym::var) {
8077
self.bump(); // `var`
81-
let msg = "write `let` instead of `var` to introduce a new variable";
82-
self.recover_stmt_local(lo, attrs, msg, "let")?
78+
self.recover_stmt_local(lo, attrs, InvalidVariableDeclarationSub::UseLetNotVar)?
8379
} else if self.check_path() && !self.token.is_qpath_start() && !self.is_path_start_item() {
8480
// We have avoided contextual keywords like `union`, items with `crate` visibility,
8581
// or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
@@ -217,13 +213,10 @@ impl<'a> Parser<'a> {
217213
&mut self,
218214
lo: Span,
219215
attrs: AttrWrapper,
220-
msg: &str,
221-
sugg: &str,
216+
subdiagnostic: fn(Span) -> InvalidVariableDeclarationSub,
222217
) -> PResult<'a, Stmt> {
223218
let stmt = self.recover_local_after_let(lo, attrs)?;
224-
self.struct_span_err(lo, "invalid variable declaration")
225-
.span_suggestion(lo, msg, sugg, Applicability::MachineApplicable)
226-
.emit();
219+
self.sess.emit_err(InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) });
227220
Ok(stmt)
228221
}
229222

0 commit comments

Comments
 (0)