Skip to content

Commit

Permalink
Rollup merge of rust-lang#100565 - TaKO8Ki:suggest-adding-missing-sem…
Browse files Browse the repository at this point in the history
…icolon-before-item, r=compiler-errors

Suggest adding a missing semicolon before an item

fixes rust-lang#100533
  • Loading branch information
matthiaskrgr authored Aug 23, 2022
2 parents e568cb4 + 40dcf89 commit 54d0f50
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 2 deletions.
24 changes: 24 additions & 0 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,30 @@ impl Token {
|| self == &OpenDelim(Delimiter::Parenthesis)
}

/// Returns `true` if the token can appear at the start of an item.
pub fn can_begin_item(&self) -> bool {
match self.kind {
Ident(name, _) => [
kw::Fn,
kw::Use,
kw::Struct,
kw::Enum,
kw::Pub,
kw::Trait,
kw::Extern,
kw::Impl,
kw::Unsafe,
kw::Static,
kw::Union,
kw::Macro,
kw::Mod,
kw::Type,
]
.contains(&name),
_ => false,
}
}

/// Returns `true` if the token is any literal.
pub fn is_lit(&self) -> bool {
matches!(self.kind, Literal(..))
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -927,10 +927,12 @@ impl<'a> Parser<'a> {
return Ok(true);
} else if self.look_ahead(0, |t| {
t == &token::CloseDelim(Delimiter::Brace)
|| (t.can_begin_expr() && t != &token::Semi && t != &token::Pound)
|| ((t.can_begin_expr() || t.can_begin_item())
&& t != &token::Semi
&& t != &token::Pound)
// Avoid triggering with too many trailing `#` in raw string.
|| (sm.is_multiline(
self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo())
self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()),
) && t == &token::Pound)
}) && !expected.contains(&TokenType::Token(token::Comma))
{
Expand Down
61 changes: 61 additions & 0 deletions src/test/ui/parser/recover-missing-semi-before-item.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// run-rustfix

#![allow(unused_variables, dead_code)]

fn for_struct() {
let foo = 3; //~ ERROR expected `;`, found keyword `struct`
struct Foo;
}

fn for_union() {
let foo = 3; //~ ERROR expected `;`, found `union`
union Foo {
foo: usize,
}
}

fn for_enum() {
let foo = 3; //~ ERROR expected `;`, found keyword `enum`
enum Foo {
Bar,
}
}

fn for_fn() {
let foo = 3; //~ ERROR expected `;`, found keyword `fn`
fn foo() {}
}

fn for_extern() {
let foo = 3; //~ ERROR expected `;`, found keyword `extern`
extern fn foo() {}
}

fn for_impl() {
struct Foo;
let foo = 3; //~ ERROR expected `;`, found keyword `impl`
impl Foo {}
}

fn for_use() {
let foo = 3; //~ ERROR expected `;`, found keyword `pub`
pub use bar::Bar;
}

fn for_mod() {
let foo = 3; //~ ERROR expected `;`, found keyword `mod`
mod foo {}
}

fn for_type() {
let foo = 3; //~ ERROR expected `;`, found keyword `type`
type Foo = usize;
}

mod bar {
pub struct Bar;
}

const X: i32 = 123; //~ ERROR expected `;`, found keyword `fn`

fn main() {}
61 changes: 61 additions & 0 deletions src/test/ui/parser/recover-missing-semi-before-item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// run-rustfix

#![allow(unused_variables, dead_code)]

fn for_struct() {
let foo = 3 //~ ERROR expected `;`, found keyword `struct`
struct Foo;
}

fn for_union() {
let foo = 3 //~ ERROR expected `;`, found `union`
union Foo {
foo: usize,
}
}

fn for_enum() {
let foo = 3 //~ ERROR expected `;`, found keyword `enum`
enum Foo {
Bar,
}
}

fn for_fn() {
let foo = 3 //~ ERROR expected `;`, found keyword `fn`
fn foo() {}
}

fn for_extern() {
let foo = 3 //~ ERROR expected `;`, found keyword `extern`
extern fn foo() {}
}

fn for_impl() {
struct Foo;
let foo = 3 //~ ERROR expected `;`, found keyword `impl`
impl Foo {}
}

fn for_use() {
let foo = 3 //~ ERROR expected `;`, found keyword `pub`
pub use bar::Bar;
}

fn for_mod() {
let foo = 3 //~ ERROR expected `;`, found keyword `mod`
mod foo {}
}

fn for_type() {
let foo = 3 //~ ERROR expected `;`, found keyword `type`
type Foo = usize;
}

mod bar {
pub struct Bar;
}

const X: i32 = 123 //~ ERROR expected `;`, found keyword `fn`

fn main() {}
83 changes: 83 additions & 0 deletions src/test/ui/parser/recover-missing-semi-before-item.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
error: expected `;`, found keyword `struct`
--> $DIR/recover-missing-semi-before-item.rs:6:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | struct Foo;
| ------ unexpected token

error: expected `;`, found `union`
--> $DIR/recover-missing-semi-before-item.rs:11:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | union Foo {
| ----- unexpected token

error: expected `;`, found keyword `enum`
--> $DIR/recover-missing-semi-before-item.rs:18:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | enum Foo {
| ---- unexpected token

error: expected `;`, found keyword `fn`
--> $DIR/recover-missing-semi-before-item.rs:25:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | fn foo() {}
| -- unexpected token

error: expected `;`, found keyword `extern`
--> $DIR/recover-missing-semi-before-item.rs:30:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | extern fn foo() {}
| ------ unexpected token

error: expected `;`, found keyword `impl`
--> $DIR/recover-missing-semi-before-item.rs:36:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | impl Foo {}
| ---- unexpected token

error: expected `;`, found keyword `pub`
--> $DIR/recover-missing-semi-before-item.rs:41:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | pub use bar::Bar;
| --- unexpected token

error: expected `;`, found keyword `mod`
--> $DIR/recover-missing-semi-before-item.rs:46:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | mod foo {}
| --- unexpected token

error: expected `;`, found keyword `type`
--> $DIR/recover-missing-semi-before-item.rs:51:16
|
LL | let foo = 3
| ^ help: add `;` here
LL | type Foo = usize;
| ---- unexpected token

error: expected `;`, found keyword `fn`
--> $DIR/recover-missing-semi-before-item.rs:59:19
|
LL | const X: i32 = 123
| ^ help: add `;` here
LL |
LL | fn main() {}
| -- unexpected token

error: aborting due to 10 previous errors

0 comments on commit 54d0f50

Please sign in to comment.