Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest removing a semicolon after impl/trait items #100446

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,14 +670,44 @@ impl<'a> Parser<'a> {
}
match parse_item(self) {
Ok(None) => {
let is_unnecessary_semicolon = !items.is_empty()
// When the close delim is `)` in a case like the following, `token.kind` is expected to be `token::CloseDelim(Delimiter::Parenthesis)`,
// but the actual `token.kind` is `token::CloseDelim(Delimiter::Bracket)`.
// This is because the `token.kind` of the close delim is treated as the same as
// that of the open delim in `TokenTreesReader::parse_token_tree`, even if the delimiters of them are different.
// Therefore, `token.kind` should not be compared here.
//
// issue-60075.rs
// ```
// trait T {
// fn qux() -> Option<usize> {
// let _ = if true {
// });
// ^ this close delim
// Some(4)
// }
// ```
&& self
.span_to_snippet(self.prev_token.span)
.map_or(false, |snippet| snippet == "}")
compiler-errors marked this conversation as resolved.
Show resolved Hide resolved
&& self.token.kind == token::Semi;
let semicolon_span = self.token.span;
// We have to bail or we'll potentially never make progress.
let non_item_span = self.token.span;
self.consume_block(Delimiter::Brace, ConsumeClosingDelim::Yes);
self.struct_span_err(non_item_span, "non-item in item list")
.span_label(open_brace_span, "item list starts here")
let mut err = self.struct_span_err(non_item_span, "non-item in item list");
err.span_label(open_brace_span, "item list starts here")
.span_label(non_item_span, "non-item starts here")
.span_label(self.prev_token.span, "item list ends here")
.emit();
.span_label(self.prev_token.span, "item list ends here");
if is_unnecessary_semicolon {
err.span_suggestion(
semicolon_span,
compiler-errors marked this conversation as resolved.
Show resolved Hide resolved
"consider removing this semicolon",
"",
Applicability::MaybeIncorrect,
);
}
err.emit();
break;
}
Ok(Some(item)) => items.extend(item),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// run-rustfix

trait Foo {
fn bar() {} //~ ERROR non-item in item list
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// run-rustfix

trait Foo {
fn bar() {}; //~ ERROR non-item in item list
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: non-item in item list
--> $DIR/suggest-removing-semicolon-after-impl-trait-items.rs:4:16
|
LL | trait Foo {
| - item list starts here
LL | fn bar() {};
| ^
| |
| non-item starts here
| help: consider removing this semicolon
LL | }
| - item list ends here

error: aborting due to previous error