Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/parser/src/grammar/expressions.rs')
| -rw-r--r-- | crates/parser/src/grammar/expressions.rs | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs index e99c111d39..52a08c4fb1 100644 --- a/crates/parser/src/grammar/expressions.rs +++ b/crates/parser/src/grammar/expressions.rs @@ -611,6 +611,7 @@ fn cast_expr(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { // foo(bar::); // foo(bar:); // foo(bar+); +// foo(a, , b); // } fn arg_list(p: &mut Parser<'_>) { assert!(p.at(T!['('])); @@ -619,14 +620,30 @@ fn arg_list(p: &mut Parser<'_>) { // fn main() { // foo(#[attr] 92) // } - delimited( - p, - T!['('], - T![')'], - T![,], - EXPR_FIRST.union(ATTRIBUTE_FIRST), - |p: &mut Parser<'_>| expr(p).is_some(), - ); + p.bump(T!['(']); + while !p.at(T![')']) && !p.at(EOF) { + if p.at(T![,]) { + // Recover if an argument is missing and only got a delimiter, + // e.g. `(a, , b)`. + p.error("expected expression"); + p.bump(T![,]); + continue; + } + + if expr(p).is_none() { + break; + } + if !p.at(T![,]) { + if p.at_ts(EXPR_FIRST.union(ATTRIBUTE_FIRST)) { + p.error(format!("expected {:?}", T![,])); + } else { + break; + } + } else { + p.bump(T![,]); + } + } + p.expect(T![')']); m.complete(p, ARG_LIST); } |