Rollup merge of #105369 - chenyukang:yukang/fix-105226, r=TaKO8Ki

Detect spurious ; before assoc fn body

Fixes #105226

r? ``@TaKO8Ki``
This commit is contained in:
Matthias Krüger 2022-12-11 23:36:46 +01:00 committed by GitHub
commit 4154e14f9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 3 deletions

View File

@ -706,9 +706,9 @@ fn parse_item_list<T>(
} }
match parse_item(self) { match parse_item(self) {
Ok(None) => { 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)`, // 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 // 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. // 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. // Therefore, `token.kind` should not be compared here.
@ -727,7 +727,13 @@ fn parse_item_list<T>(
.span_to_snippet(self.prev_token.span) .span_to_snippet(self.prev_token.span)
.map_or(false, |snippet| snippet == "}") .map_or(false, |snippet| snippet == "}")
&& self.token.kind == token::Semi; && 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. // We have to bail or we'll potentially never make progress.
let non_item_span = self.token.span; let non_item_span = self.token.span;
let is_let = self.token.is_keyword(kw::Let); let is_let = self.token.is_keyword(kw::Let);

View File

@ -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);
}

View File

@ -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