Skip to content

Commit 54d0f50

Browse files
authored
Rollup merge of #100565 - TaKO8Ki:suggest-adding-missing-semicolon-before-item, r=compiler-errors
Suggest adding a missing semicolon before an item fixes #100533
2 parents e568cb4 + 40dcf89 commit 54d0f50

File tree

5 files changed

+233
-2
lines changed

5 files changed

+233
-2
lines changed

compiler/rustc_ast/src/token.rs

+24
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,30 @@ impl Token {
436436
|| self == &OpenDelim(Delimiter::Parenthesis)
437437
}
438438

439+
/// Returns `true` if the token can appear at the start of an item.
440+
pub fn can_begin_item(&self) -> bool {
441+
match self.kind {
442+
Ident(name, _) => [
443+
kw::Fn,
444+
kw::Use,
445+
kw::Struct,
446+
kw::Enum,
447+
kw::Pub,
448+
kw::Trait,
449+
kw::Extern,
450+
kw::Impl,
451+
kw::Unsafe,
452+
kw::Static,
453+
kw::Union,
454+
kw::Macro,
455+
kw::Mod,
456+
kw::Type,
457+
]
458+
.contains(&name),
459+
_ => false,
460+
}
461+
}
462+
439463
/// Returns `true` if the token is any literal.
440464
pub fn is_lit(&self) -> bool {
441465
matches!(self.kind, Literal(..))

compiler/rustc_parse/src/parser/diagnostics.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -927,10 +927,12 @@ impl<'a> Parser<'a> {
927927
return Ok(true);
928928
} else if self.look_ahead(0, |t| {
929929
t == &token::CloseDelim(Delimiter::Brace)
930-
|| (t.can_begin_expr() && t != &token::Semi && t != &token::Pound)
930+
|| ((t.can_begin_expr() || t.can_begin_item())
931+
&& t != &token::Semi
932+
&& t != &token::Pound)
931933
// Avoid triggering with too many trailing `#` in raw string.
932934
|| (sm.is_multiline(
933-
self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo())
935+
self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()),
934936
) && t == &token::Pound)
935937
}) && !expected.contains(&TokenType::Token(token::Comma))
936938
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// run-rustfix
2+
3+
#![allow(unused_variables, dead_code)]
4+
5+
fn for_struct() {
6+
let foo = 3; //~ ERROR expected `;`, found keyword `struct`
7+
struct Foo;
8+
}
9+
10+
fn for_union() {
11+
let foo = 3; //~ ERROR expected `;`, found `union`
12+
union Foo {
13+
foo: usize,
14+
}
15+
}
16+
17+
fn for_enum() {
18+
let foo = 3; //~ ERROR expected `;`, found keyword `enum`
19+
enum Foo {
20+
Bar,
21+
}
22+
}
23+
24+
fn for_fn() {
25+
let foo = 3; //~ ERROR expected `;`, found keyword `fn`
26+
fn foo() {}
27+
}
28+
29+
fn for_extern() {
30+
let foo = 3; //~ ERROR expected `;`, found keyword `extern`
31+
extern fn foo() {}
32+
}
33+
34+
fn for_impl() {
35+
struct Foo;
36+
let foo = 3; //~ ERROR expected `;`, found keyword `impl`
37+
impl Foo {}
38+
}
39+
40+
fn for_use() {
41+
let foo = 3; //~ ERROR expected `;`, found keyword `pub`
42+
pub use bar::Bar;
43+
}
44+
45+
fn for_mod() {
46+
let foo = 3; //~ ERROR expected `;`, found keyword `mod`
47+
mod foo {}
48+
}
49+
50+
fn for_type() {
51+
let foo = 3; //~ ERROR expected `;`, found keyword `type`
52+
type Foo = usize;
53+
}
54+
55+
mod bar {
56+
pub struct Bar;
57+
}
58+
59+
const X: i32 = 123; //~ ERROR expected `;`, found keyword `fn`
60+
61+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// run-rustfix
2+
3+
#![allow(unused_variables, dead_code)]
4+
5+
fn for_struct() {
6+
let foo = 3 //~ ERROR expected `;`, found keyword `struct`
7+
struct Foo;
8+
}
9+
10+
fn for_union() {
11+
let foo = 3 //~ ERROR expected `;`, found `union`
12+
union Foo {
13+
foo: usize,
14+
}
15+
}
16+
17+
fn for_enum() {
18+
let foo = 3 //~ ERROR expected `;`, found keyword `enum`
19+
enum Foo {
20+
Bar,
21+
}
22+
}
23+
24+
fn for_fn() {
25+
let foo = 3 //~ ERROR expected `;`, found keyword `fn`
26+
fn foo() {}
27+
}
28+
29+
fn for_extern() {
30+
let foo = 3 //~ ERROR expected `;`, found keyword `extern`
31+
extern fn foo() {}
32+
}
33+
34+
fn for_impl() {
35+
struct Foo;
36+
let foo = 3 //~ ERROR expected `;`, found keyword `impl`
37+
impl Foo {}
38+
}
39+
40+
fn for_use() {
41+
let foo = 3 //~ ERROR expected `;`, found keyword `pub`
42+
pub use bar::Bar;
43+
}
44+
45+
fn for_mod() {
46+
let foo = 3 //~ ERROR expected `;`, found keyword `mod`
47+
mod foo {}
48+
}
49+
50+
fn for_type() {
51+
let foo = 3 //~ ERROR expected `;`, found keyword `type`
52+
type Foo = usize;
53+
}
54+
55+
mod bar {
56+
pub struct Bar;
57+
}
58+
59+
const X: i32 = 123 //~ ERROR expected `;`, found keyword `fn`
60+
61+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
error: expected `;`, found keyword `struct`
2+
--> $DIR/recover-missing-semi-before-item.rs:6:16
3+
|
4+
LL | let foo = 3
5+
| ^ help: add `;` here
6+
LL | struct Foo;
7+
| ------ unexpected token
8+
9+
error: expected `;`, found `union`
10+
--> $DIR/recover-missing-semi-before-item.rs:11:16
11+
|
12+
LL | let foo = 3
13+
| ^ help: add `;` here
14+
LL | union Foo {
15+
| ----- unexpected token
16+
17+
error: expected `;`, found keyword `enum`
18+
--> $DIR/recover-missing-semi-before-item.rs:18:16
19+
|
20+
LL | let foo = 3
21+
| ^ help: add `;` here
22+
LL | enum Foo {
23+
| ---- unexpected token
24+
25+
error: expected `;`, found keyword `fn`
26+
--> $DIR/recover-missing-semi-before-item.rs:25:16
27+
|
28+
LL | let foo = 3
29+
| ^ help: add `;` here
30+
LL | fn foo() {}
31+
| -- unexpected token
32+
33+
error: expected `;`, found keyword `extern`
34+
--> $DIR/recover-missing-semi-before-item.rs:30:16
35+
|
36+
LL | let foo = 3
37+
| ^ help: add `;` here
38+
LL | extern fn foo() {}
39+
| ------ unexpected token
40+
41+
error: expected `;`, found keyword `impl`
42+
--> $DIR/recover-missing-semi-before-item.rs:36:16
43+
|
44+
LL | let foo = 3
45+
| ^ help: add `;` here
46+
LL | impl Foo {}
47+
| ---- unexpected token
48+
49+
error: expected `;`, found keyword `pub`
50+
--> $DIR/recover-missing-semi-before-item.rs:41:16
51+
|
52+
LL | let foo = 3
53+
| ^ help: add `;` here
54+
LL | pub use bar::Bar;
55+
| --- unexpected token
56+
57+
error: expected `;`, found keyword `mod`
58+
--> $DIR/recover-missing-semi-before-item.rs:46:16
59+
|
60+
LL | let foo = 3
61+
| ^ help: add `;` here
62+
LL | mod foo {}
63+
| --- unexpected token
64+
65+
error: expected `;`, found keyword `type`
66+
--> $DIR/recover-missing-semi-before-item.rs:51:16
67+
|
68+
LL | let foo = 3
69+
| ^ help: add `;` here
70+
LL | type Foo = usize;
71+
| ---- unexpected token
72+
73+
error: expected `;`, found keyword `fn`
74+
--> $DIR/recover-missing-semi-before-item.rs:59:19
75+
|
76+
LL | const X: i32 = 123
77+
| ^ help: add `;` here
78+
LL |
79+
LL | fn main() {}
80+
| -- unexpected token
81+
82+
error: aborting due to 10 previous errors
83+

0 commit comments

Comments
 (0)