Skip to content

Commit

Permalink
fix #105226, Detect spurious ; before assoc fn body
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyukang committed Dec 7, 2022
1 parent 703d95e commit 5599f2a
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
12 changes: 9 additions & 3 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,9 +707,9 @@ impl<'a> Parser<'a> {
}
match parse_item(self) {
Ok(None) => {
let is_unnecessary_semicolon = !items.is_empty()
let mut 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)`.
// but the actual `token.kind` is `token::CloseDelim(Delimiter::Brace)`.
// 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.
Expand All @@ -728,7 +728,13 @@ impl<'a> Parser<'a> {
.span_to_snippet(self.prev_token.span)
.map_or(false, |snippet| snippet == "}")
&& self.token.kind == token::Semi;
let semicolon_span = self.token.span;
let mut semicolon_span = self.token.span;
if !is_unnecessary_semicolon {
// #105369, Detect spurious `;` before assoc fn body
is_unnecessary_semicolon = self.token == token::OpenDelim(Delimiter::Brace)
&& self.prev_token.kind == token::Semi;
semicolon_span = self.prev_token.span;
}
// We have to bail or we'll potentially never make progress.
let non_item_span = self.token.span;
let is_let = self.token.is_keyword(kw::Let);
Expand Down
22 changes: 22 additions & 0 deletions src/test/ui/suggestions/issue-105226.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use std::fmt;

struct S {
}

impl S {
fn hello<P>(&self, val: &P) where P: fmt::Display; {
//~^ ERROR non-item in item list
//~| ERROR associated function in `impl` without body
println!("val: {}", val);
}
}

impl S {
fn hello_empty<P>(&self, val: &P) where P: fmt::Display;
//~^ ERROR associated function in `impl` without body
}

fn main() {
let s = S{};
s.hello(&32);
}
31 changes: 31 additions & 0 deletions src/test/ui/suggestions/issue-105226.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
error: non-item in item list
--> $DIR/issue-105226.rs:7:56
|
LL | impl S {
| - item list starts here
LL | fn hello<P>(&self, val: &P) where P: fmt::Display; {
| - ^ non-item starts here
| |
| help: consider removing this semicolon
...
LL | }
| - item list ends here

error: associated function in `impl` without body
--> $DIR/issue-105226.rs:7:5
|
LL | fn hello<P>(&self, val: &P) where P: fmt::Display; {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: provide a definition for the function: `{ <body> }`

error: associated function in `impl` without body
--> $DIR/issue-105226.rs:15:5
|
LL | fn hello_empty<P>(&self, val: &P) where P: fmt::Display;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: provide a definition for the function: `{ <body> }`

error: aborting due to 3 previous errors

0 comments on commit 5599f2a

Please sign in to comment.