about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_parse/src/parser/item.rs28
-rw-r--r--src/test/ui/parser/fn-field-parse-error-ice.rs2
-rw-r--r--src/test/ui/parser/fn-field-parse-error-ice.stderr10
-rw-r--r--src/test/ui/structs/incomplete-fn-in-struct-definition.rs5
-rw-r--r--src/test/ui/structs/incomplete-fn-in-struct-definition.stderr15
5 files changed, 44 insertions, 16 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index c8a8e00b1fa..25425fbb2c6 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1753,18 +1753,24 @@ impl<'a> Parser<'a> {
                 };
                 // We use `parse_fn` to get a span for the function
                 let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
-                if let Err(mut db) =
-                    self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis)
-                {
-                    db.delay_as_bug();
+                match self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis) {
+                    Ok(_) => {
+                        let mut err = self.struct_span_err(
+                            lo.to(self.prev_token.span),
+                            &format!("functions are not allowed in {adt_ty} definitions"),
+                        );
+                        err.help(
+                            "unlike in C++, Java, and C#, functions are declared in `impl` blocks",
+                        );
+                        err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
+                        err
+                    }
+                    Err(err) => {
+                        err.cancel();
+                        self.restore_snapshot(snapshot);
+                        self.expected_ident_found()
+                    }
                 }
-                let mut err = self.struct_span_err(
-                    lo.to(self.prev_token.span),
-                    &format!("functions are not allowed in {adt_ty} definitions"),
-                );
-                err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks");
-                err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
-                err
             } else if self.eat_keyword(kw::Struct) {
                 match self.parse_item_struct() {
                     Ok((ident, _)) => {
diff --git a/src/test/ui/parser/fn-field-parse-error-ice.rs b/src/test/ui/parser/fn-field-parse-error-ice.rs
index 4ea55062fc4..188257ea53a 100644
--- a/src/test/ui/parser/fn-field-parse-error-ice.rs
+++ b/src/test/ui/parser/fn-field-parse-error-ice.rs
@@ -3,7 +3,7 @@
 struct Baz {
     inner : dyn fn ()
     //~^ ERROR expected `,`, or `}`, found keyword `fn`
-    //~| ERROR functions are not allowed in struct definitions
+    //~| ERROR expected identifier, found keyword `fn`
     //~| ERROR cannot find type `dyn` in this scope
 }
 
diff --git a/src/test/ui/parser/fn-field-parse-error-ice.stderr b/src/test/ui/parser/fn-field-parse-error-ice.stderr
index e9583f55b8e..3bf68e8cc04 100644
--- a/src/test/ui/parser/fn-field-parse-error-ice.stderr
+++ b/src/test/ui/parser/fn-field-parse-error-ice.stderr
@@ -4,16 +4,18 @@ error: expected `,`, or `}`, found keyword `fn`
 LL |     inner : dyn fn ()
    |                ^ help: try adding a comma: `,`
 
-error: functions are not allowed in struct definitions
+error: expected identifier, found keyword `fn`
   --> $DIR/fn-field-parse-error-ice.rs:4:17
    |
 LL | struct Baz {
    |        --- while parsing this struct
 LL |     inner : dyn fn ()
-   |                 ^^
+   |                 ^^ expected identifier, found keyword
    |
-   = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
-   = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
+help: escape `fn` to use it as an identifier
+   |
+LL |     inner : dyn r#fn ()
+   |                 ++
 
 error[E0412]: cannot find type `dyn` in this scope
   --> $DIR/fn-field-parse-error-ice.rs:4:13
diff --git a/src/test/ui/structs/incomplete-fn-in-struct-definition.rs b/src/test/ui/structs/incomplete-fn-in-struct-definition.rs
new file mode 100644
index 00000000000..cd8a79ba687
--- /dev/null
+++ b/src/test/ui/structs/incomplete-fn-in-struct-definition.rs
@@ -0,0 +1,5 @@
+fn main() {}
+
+struct S {
+    fn: u8 //~ ERROR expected identifier, found keyword `fn`
+}
diff --git a/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr b/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr
new file mode 100644
index 00000000000..0d12ba9c916
--- /dev/null
+++ b/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr
@@ -0,0 +1,15 @@
+error: expected identifier, found keyword `fn`
+  --> $DIR/incomplete-fn-in-struct-definition.rs:4:5
+   |
+LL | struct S {
+   |        - while parsing this struct
+LL |     fn: u8
+   |     ^^ expected identifier, found keyword
+   |
+help: escape `fn` to use it as an identifier
+   |
+LL |     r#fn: u8
+   |     ++
+
+error: aborting due to previous error
+