about summary refs log tree commit diff
diff options
context:
space:
mode:
authorfee1-dead <ent3rm4n@gmail.com>2022-09-26 13:09:41 +0800
committerGitHub <noreply@github.com>2022-09-26 13:09:41 +0800
commit0adf293f87fb354bf9a44e3e2f1c2b5a3578d880 (patch)
treede6db736182f66faf40c4b7b90bca3695a56dd45
parent3288d3a305ad15cfcdcd9ef72404be6d2a2887b5 (diff)
parentc66c2e82c1a405ed3fff99953ab96de03806ca09 (diff)
downloadrust-0adf293f87fb354bf9a44e3e2f1c2b5a3578d880.tar.gz
rust-0adf293f87fb354bf9a44e3e2f1c2b5a3578d880.zip
Rollup merge of #102143 - Rageking8:fix-101540, r=TaKO8Ki
Recover from struct nested in struct

Fixes #101540

r? `@TaKO8Ki`

Not sure If I have done it right.
-rw-r--r--compiler/rustc_parse/src/parser/item.rs17
-rw-r--r--src/test/ui/parser/issues/issue-101540.rs7
-rw-r--r--src/test/ui/parser/issues/issue-101540.stderr10
3 files changed, 34 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index e55b5ce71cd..e385ac44113 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1715,6 +1715,7 @@ impl<'a> Parser<'a> {
     fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
         let (ident, is_raw) = self.ident_or_err()?;
         if !is_raw && ident.is_reserved() {
+            let snapshot = self.create_snapshot_for_diagnostic();
             let err = if self.check_fn_front_matter(false) {
                 let inherited_vis = Visibility {
                     span: rustc_span::DUMMY_SP,
@@ -1735,6 +1736,22 @@ impl<'a> Parser<'a> {
                 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, _)) => {
+                        let mut err = self.struct_span_err(
+                            lo.with_hi(ident.span.hi()),
+                            &format!("structs are not allowed in {adt_ty} definitions"),
+                        );
+                        err.help("consider creating a new `struct` definition instead of nesting");
+                        err
+                    }
+                    Err(err) => {
+                        err.cancel();
+                        self.restore_snapshot(snapshot);
+                        self.expected_ident_found()
+                    }
+                }
             } else {
                 self.expected_ident_found()
             };
diff --git a/src/test/ui/parser/issues/issue-101540.rs b/src/test/ui/parser/issues/issue-101540.rs
new file mode 100644
index 00000000000..328ec6f906b
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-101540.rs
@@ -0,0 +1,7 @@
+struct S1 {
+    struct S2 {
+    //~^ ERROR structs are not allowed in struct definitions
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issues/issue-101540.stderr b/src/test/ui/parser/issues/issue-101540.stderr
new file mode 100644
index 00000000000..53c7c9590e6
--- /dev/null
+++ b/src/test/ui/parser/issues/issue-101540.stderr
@@ -0,0 +1,10 @@
+error: structs are not allowed in struct definitions
+  --> $DIR/issue-101540.rs:2:5
+   |
+LL |     struct S2 {
+   |     ^^^^^^^^^
+   |
+   = help: consider creating a new `struct` definition instead of nesting
+
+error: aborting due to previous error
+