Skip to content

Commit 4edbda5

Browse files
committed
Recover from let outside function
1 parent 35bb73e commit 4edbda5

File tree

3 files changed

+33
-9
lines changed

3 files changed

+33
-9
lines changed

compiler/rustc_parse/locales/en-US.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ parse_visibility_not_followed_by_item = visibility `{$vis}` is not followed by a
442442
parse_visibility_followed_by_let = visibility does not apply to `let` statement
443443
.suggestion = remove pub
444444
445+
parse_invalid_let_outside_function = `let` is invalid outside of a function
446+
.suggestion_static = consider using `static` instead of `let`
447+
.suggestion_const = consider using `const` instead of `let`
448+
445449
parse_default_not_followed_by_item = `default` is not followed by an item
446450
.label = the `default` qualifier
447451
.note = only `fn`, `const`, `type`, or `impl` items may be prefixed by `default`

compiler/rustc_parse/src/errors.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,25 @@ pub(crate) struct VisibilityFollowedByLet {
14111411
pub span: Span,
14121412
}
14131413

1414+
#[derive(Diagnostic)]
1415+
#[diag(parse_invalid_let_outside_function)]
1416+
pub(crate) struct InvalidLetOutsideFunction {
1417+
#[primary_span]
1418+
#[suggestion(
1419+
parse_suggestion_static,
1420+
style = "verbose",
1421+
code = "static",
1422+
applicability = "machine-applicable"
1423+
)]
1424+
#[suggestion(
1425+
parse_suggestion_const,
1426+
style = "verbose",
1427+
code = "const",
1428+
applicability = "machine-applicable"
1429+
)]
1430+
pub span: Span,
1431+
}
1432+
14141433
#[derive(Diagnostic)]
14151434
#[diag(parse_default_not_followed_by_item)]
14161435
#[note]

compiler/rustc_parse/src/parser/item.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,17 @@ impl<'a> Parser<'a> {
6868
}
6969

7070
if !self.eat(term) {
71-
let token_str = super::token_descr(&self.token);
7271
if !self.maybe_consume_incorrect_semicolon(&items) {
73-
let msg = &format!("expected item, found {token_str}");
74-
let mut err = self.struct_span_err(self.token.span, msg);
75-
let label = if self.is_kw_followed_by_ident(kw::Let) {
76-
"consider using `const` or `static` instead of `let` for global variables"
77-
} else {
78-
"expected item"
79-
};
80-
err.span_label(self.token.span, label);
72+
if self.is_kw_followed_by_ident(kw::Let) {
73+
let err = self
74+
.sess
75+
.create_err(errors::InvalidLetOutsideFunction { span: self.token.span });
76+
return Err(err);
77+
}
78+
let token_str = super::token_descr(&self.token);
79+
let mut err = self
80+
.struct_span_err(self.token.span, &format!("expected item, found {token_str}"));
81+
err.span_label(self.token.span, "expected item");
8182
return Err(err);
8283
}
8384
}

0 commit comments

Comments
 (0)