diff options
Diffstat (limited to 'src/syntax')
| -rw-r--r-- | src/syntax/ast.rs | 6 | ||||
| -rw-r--r-- | src/syntax/parser.rs | 15 |
2 files changed, 17 insertions, 4 deletions
diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs index 4119802e..e492297a 100644 --- a/src/syntax/ast.rs +++ b/src/syntax/ast.rs @@ -1570,7 +1570,7 @@ pub enum Param { /// A named parameter with a default value: `draw: false`. Named(Named), /// An argument sink: `..args`. - Sink(Ident), + Sink(Option<Ident>), } impl AstNode for Param { @@ -1578,7 +1578,7 @@ impl AstNode for Param { match node.kind() { SyntaxKind::Ident => node.cast().map(Self::Pos), SyntaxKind::Named => node.cast().map(Self::Named), - SyntaxKind::Spread => node.cast_first_match().map(Self::Sink), + SyntaxKind::Spread => Some(Self::Sink(node.cast_first_match())), _ => Option::None, } } @@ -1587,7 +1587,7 @@ impl AstNode for Param { match self { Self::Pos(v) => v.as_untyped(), Self::Named(v) => v.as_untyped(), - Self::Sink(v) => v.as_untyped(), + Self::Sink(_) => self.as_untyped(), } } } diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs index 42183f3a..7c05eebc 100644 --- a/src/syntax/parser.rs +++ b/src/syntax/parser.rs @@ -1069,6 +1069,7 @@ fn validate_dict(p: &mut Parser, m: Marker) { } fn validate_params(p: &mut Parser, m: Marker) { + let mut used_spread = false; let mut used = HashSet::new(); for child in p.post_process(m) { match child.kind() { @@ -1086,12 +1087,24 @@ fn validate_params(p: &mut Parser, m: Marker) { } SyntaxKind::Spread => { let Some(within) = child.children_mut().last_mut() else { continue }; - if within.kind() != SyntaxKind::Ident { + if used_spread { + child.convert_to_error("only one argument sink is allowed"); + continue; + } + used_spread = true; + if within.kind() == SyntaxKind::Dots { + continue; + } else if within.kind() != SyntaxKind::Ident { within.convert_to_error(eco_format!( "expected identifier, found {}", within.kind().name(), )); child.make_erroneous(); + continue; + } + if !used.insert(within.text().clone()) { + within.convert_to_error("duplicate parameter"); + child.make_erroneous(); } } SyntaxKind::LeftParen | SyntaxKind::RightParen | SyntaxKind::Comma => {} |
