Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/parser/src/grammar.rs')
-rw-r--r--crates/parser/src/grammar.rs94
1 files changed, 54 insertions, 40 deletions
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 1ff8a56b58..0623e7ea19 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -228,50 +228,64 @@ fn opt_visibility(p: &mut Parser<'_>, in_tuple_field: bool) -> bool {
let m = p.start();
p.bump(T![pub]);
- if p.at(T!['(']) {
- match p.nth(1) {
- // test crate_visibility
- // pub(crate) struct S;
- // 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] | 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));
- // struct MyStruct(pub (u32));
- // struct MyStruct(pub ());
- if !(in_tuple_field && matches!(p.nth(1), T![ident] | T![')'])) {
- p.bump(T!['(']);
- paths::vis_path(p);
- p.expect(T![')']);
- }
- }
- // test crate_visibility_in
- // pub(in super::A) struct S;
- // pub(in crate) struct S;
- T![in] => {
- p.bump(T!['(']);
- p.bump(T![in]);
- paths::vis_path(p);
- p.expect(T![')']);
- }
- _ => {}
- }
- }
+ opt_visibility_inner(p, in_tuple_field);
m.complete(p, VISIBILITY);
true
}
+fn opt_visibility_inner(p: &mut Parser<'_>, in_tuple_field: bool) -> bool {
+ if !p.at(T!['(']) {
+ return false;
+ }
+
+ match p.nth(1) {
+ // test crate_visibility
+ // pub(crate) struct S;
+ // 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] | 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));
+ // struct MyStruct(pub (u32));
+ // struct MyStruct(pub ());
+ && !(in_tuple_field && matches!(p.nth(1), T![ident] | T![')'])) =>
+ {
+ let m = p.start();
+ p.bump(T!['(']);
+ paths::vis_path(p);
+ p.expect(T![')']);
+ m.complete(p, VISIBILITY_INNER);
+ return true;
+ }
+ // test crate_visibility_in
+ // pub(in super::A) struct S;
+ // pub(in crate) struct S;
+ T![in] => {
+ let m = p.start();
+ p.bump(T!['(']);
+ p.bump(T![in]);
+ paths::vis_path(p);
+ p.expect(T![')']);
+ m.complete(p, VISIBILITY_INNER);
+ return true;
+ }
+ _ => {}
+ }
+ false
+}
+
fn opt_rename(p: &mut Parser<'_>) {
if p.at(T![as]) {
let m = p.start();