about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-03-30 13:08:14 +0000
committerbors <bors@rust-lang.org>2023-03-30 13:08:14 +0000
commit5c6a38abde764c4b2838017d0046f7324d559d3a (patch)
tree6114c96573c11f838e7c7d1bb1d98b920e8c8206
parent5390949c119ce53e3467bb05e19c38eef5dac3b8 (diff)
parentcb546390daba33b72b8bb6a7d8179fede7183984 (diff)
downloadrust-5c6a38abde764c4b2838017d0046f7324d559d3a.tar.gz
rust-5c6a38abde764c4b2838017d0046f7324d559d3a.zip
Auto merge of #14449 - Veykril:parser-vis-recov, r=Veykril
fix: Recover from `pub()` visibility modifier
-rw-r--r--crates/parser/src/grammar.rs11
-rw-r--r--crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rast18
-rw-r--r--crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rast39
-rw-r--r--crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rs2
5 files changed, 68 insertions, 3 deletions
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 15435a26cea..e2fb1d1aced 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -218,17 +218,22 @@ fn opt_visibility(p: &mut Parser<'_>, in_tuple_field: bool) -> bool {
                     // pub(self) struct S;
                     // pub(super) struct S;
 
+                    // test_err crate_visibility_empty_recover
+                    // pub() struct S;
+
                     // test pub_parens_typepath
                     // struct B(pub (super::A));
                     // struct B(pub (crate::A,));
-                    T![crate] | T![self] | T![super] | T![ident] if p.nth(2) != T![:] => {
+                    T![crate] | T![self] | T![super] | T![ident] | T![')'] if p.nth(2) != T![:] => {
                         // If we are in a tuple struct, then the parens following `pub`
                         // might be an tuple field, not part of the visibility. So in that
                         // case we don't want to consume an identifier.
 
                         // test pub_tuple_field
                         // struct MyStruct(pub (u32, u32));
-                        if !(in_tuple_field && matches!(p.nth(1), T![ident])) {
+                        // struct MyStruct(pub (u32));
+                        // struct MyStruct(pub ());
+                        if !(in_tuple_field && matches!(p.nth(1), T![ident] | T![')'])) {
                             p.bump(T!['(']);
                             paths::use_path(p);
                             p.expect(T![')']);
@@ -243,7 +248,7 @@ fn opt_visibility(p: &mut Parser<'_>, in_tuple_field: bool) -> bool {
                         paths::use_path(p);
                         p.expect(T![')']);
                     }
-                    _ => (),
+                    _ => {}
                 }
             }
             m.complete(p, VISIBILITY);
diff --git a/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rast b/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rast
new file mode 100644
index 00000000000..0fe4ca42d79
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rast
@@ -0,0 +1,18 @@
+SOURCE_FILE
+  STRUCT
+    VISIBILITY
+      PUB_KW "pub"
+      L_PAREN "("
+      PATH
+        PATH_SEGMENT
+          ERROR
+            R_PAREN ")"
+    WHITESPACE " "
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "S"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+error 4: expected identifier
+error 5: expected R_PAREN
diff --git a/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rs b/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rs
new file mode 100644
index 00000000000..e8cf9e6696d
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rs
@@ -0,0 +1 @@
+pub() struct S;
diff --git a/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rast b/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rast
index a23ddf69f25..c78d16f064c 100644
--- a/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rast
+++ b/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rast
@@ -28,3 +28,42 @@ SOURCE_FILE
       R_PAREN ")"
     SEMICOLON ";"
   WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "MyStruct"
+    TUPLE_FIELD_LIST
+      L_PAREN "("
+      TUPLE_FIELD
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        PAREN_TYPE
+          L_PAREN "("
+          PATH_TYPE
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "u32"
+          R_PAREN ")"
+      R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
+  STRUCT
+    STRUCT_KW "struct"
+    WHITESPACE " "
+    NAME
+      IDENT "MyStruct"
+    TUPLE_FIELD_LIST
+      L_PAREN "("
+      TUPLE_FIELD
+        VISIBILITY
+          PUB_KW "pub"
+        WHITESPACE " "
+        TUPLE_TYPE
+          L_PAREN "("
+          R_PAREN ")"
+      R_PAREN ")"
+    SEMICOLON ";"
+  WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rs b/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rs
index 00d8feba967..6f725fb7b98 100644
--- a/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rs
+++ b/crates/parser/test_data/parser/inline/ok/0196_pub_tuple_field.rs
@@ -1 +1,3 @@
 struct MyStruct(pub (u32, u32));
+struct MyStruct(pub (u32));
+struct MyStruct(pub ());