about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-12-11 23:36:46 +0100
committerGitHub <noreply@github.com>2022-12-11 23:36:46 +0100
commit4154e14f9ac586b4bb8c67db1d474b4d8c960e23 (patch)
treeb7ba9e369484a79c05e7086a42fd332bab3cf360
parentaa7b5b32e3463fc21468073ca3a75e2c3617b179 (diff)
parent5599f2ad09345b94487920b84029ad215c4dc743 (diff)
downloadrust-4154e14f9ac586b4bb8c67db1d474b4d8c960e23.tar.gz
rust-4154e14f9ac586b4bb8c67db1d474b4d8c960e23.zip
Rollup merge of #105369 - chenyukang:yukang/fix-105226, r=TaKO8Ki
Detect spurious ; before assoc fn body

Fixes #105226

r? ``@TaKO8Ki``
-rw-r--r--compiler/rustc_parse/src/parser/item.rs12
-rw-r--r--src/test/ui/suggestions/issue-105226.rs22
-rw-r--r--src/test/ui/suggestions/issue-105226.stderr31
3 files changed, 62 insertions, 3 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 7ebcda249e2..beb9d55d454 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -706,9 +706,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.
@@ -727,7 +727,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);
diff --git a/src/test/ui/suggestions/issue-105226.rs b/src/test/ui/suggestions/issue-105226.rs
new file mode 100644
index 00000000000..f123dbf4cae
--- /dev/null
+++ b/src/test/ui/suggestions/issue-105226.rs
@@ -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);
+}
diff --git a/src/test/ui/suggestions/issue-105226.stderr b/src/test/ui/suggestions/issue-105226.stderr
new file mode 100644
index 00000000000..f16a8090103
--- /dev/null
+++ b/src/test/ui/suggestions/issue-105226.stderr
@@ -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
+