Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/parser/src/grammar/expressions/atom.rs')
| -rw-r--r-- | crates/parser/src/grammar/expressions/atom.rs | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index 407320e1d0..c66afed91c 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -258,6 +258,15 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> { p.expect(T!['(']); type_(p); p.expect(T![,]); + // Due to our incomplete handling of macro groups, especially + // those with empty delimiters, we wrap `expr` fragments in + // parentheses sometimes. Since `offset_of` is a macro, and takes + // `expr`, the field names could be wrapped in parentheses. + let wrapped_in_parens = p.eat(T!['(']); + // test offset_of_parens + // fn foo() { + // builtin#offset_of(Foo, (bar.baz.0)); + // } while !p.at(EOF) && !p.at(T![')']) { name_ref_mod_path_or_index(p); if !p.at(T![')']) { @@ -265,6 +274,9 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option<CompletedMarker> { } } p.expect(T![')']); + if wrapped_in_parens { + p.expect(T![')']); + } Some(m.complete(p, OFFSET_OF_EXPR)) } else if p.at_contextual_kw(T![format_args]) { p.bump_remap(T![format_args]); |