From cb546390daba33b72b8bb6a7d8179fede7183984 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 30 Mar 2023 13:41:31 +0200 Subject: [PATCH] fix: Recover from `pub()` visibility modifier --- crates/parser/src/grammar.rs | 11 ++++-- .../0018_crate_visibility_empty_recover.rast | 18 +++++++++ .../0018_crate_visibility_empty_recover.rs | 1 + .../inline/ok/0196_pub_tuple_field.rast | 39 +++++++++++++++++++ .../parser/inline/ok/0196_pub_tuple_field.rs | 2 + 5 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rast create mode 100644 crates/parser/test_data/parser/inline/err/0018_crate_visibility_empty_recover.rs diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index 15435a26ce..e2fb1d1ace 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 0000000000..0fe4ca42d7 --- /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 0000000000..e8cf9e6696 --- /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 a23ddf69f2..c78d16f064 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 00d8feba96..6f725fb7b9 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 ());