diff --git a/crates/aiken-lang/src/parser.rs b/crates/aiken-lang/src/parser.rs index 8eb38b3a..c7c50ebe 100644 --- a/crates/aiken-lang/src/parser.rs +++ b/crates/aiken-lang/src/parser.rs @@ -1388,7 +1388,10 @@ pub fn type_parser() -> impl Parser .separated_by(just(Token::Comma)) .at_least(2) .allow_trailing() - .delimited_by(just(Token::LeftParen), just(Token::RightParen)) + .delimited_by( + choice((just(Token::LeftParen), just(Token::NewLineLeftParen))), + just(Token::RightParen), + ) .map_with_span(|elems, span| ast::Annotation::Tuple { location: span, elems, diff --git a/crates/aiken-lang/src/tests/parser.rs b/crates/aiken-lang/src/tests/parser.rs index 2038da78..0813505d 100644 --- a/crates/aiken-lang/src/tests/parser.rs +++ b/crates/aiken-lang/src/tests/parser.rs @@ -1911,3 +1911,40 @@ fn function_ambiguous_sequence() { ], ) } + +#[test] +fn tuple_type_alias() { + let code = indoc! {r#" + type RoyaltyToken = + (PolicyId, AssetName) + "#}; + + assert_definitions( + code, + vec![ast::UntypedDefinition::TypeAlias(TypeAlias { + alias: "RoyaltyToken".to_string(), + annotation: ast::Annotation::Tuple { + location: Span::new((), 22..43), + elems: vec![ + ast::Annotation::Constructor { + location: Span::new((), 23..31), + module: None, + name: "PolicyId".to_string(), + arguments: vec![], + }, + ast::Annotation::Constructor { + location: Span::new((), 33..42), + module: None, + name: "AssetName".to_string(), + arguments: vec![], + }, + ], + }, + doc: None, + location: Span::new((), 0..43), + parameters: vec![], + public: false, + tipo: (), + })], + ) +}