diff --git a/cl-ast/src/lib.rs b/cl-ast/src/lib.rs index 66afb75..3e3c671 100644 --- a/cl-ast/src/lib.rs +++ b/cl-ast/src/lib.rs @@ -238,7 +238,7 @@ pub enum TyKind { /// A tuple of [Ty]pes #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct TyTuple { - pub types: Vec, + pub types: Vec, } /// A [Ty]pe-reference expression as (number of `&`, [Path]) @@ -251,7 +251,7 @@ pub struct TyRef { /// The args and return value for a function pointer [Ty]pe #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct TyFn { - pub args: TyTuple, + pub args: Box, pub rety: Option>, } diff --git a/cl-parser/src/parser.rs b/cl-parser/src/parser.rs index b988c13..c69a0d9 100644 --- a/cl-parser/src/parser.rs +++ b/cl-parser/src/parser.rs @@ -631,7 +631,13 @@ impl<'t> Parser<'t> { TyKind::SelfTy } TokenKind::Punct(Punct::Amp) | TokenKind::Punct(Punct::AmpAmp) => self.tyref()?.into(), - TokenKind::Punct(Punct::LParen) => self.tytuple()?.into(), + TokenKind::Punct(Punct::LParen) => { + let out = self.tytuple()?; + match out.types.is_empty() { + true => TyKind::Empty, + false => TyKind::Tuple(out), + } + } TokenKind::Fn => self.tyfn()?.into(), path_like!() => self.path()?.into(), t => Err(self.error(Unexpected(t), PARSING))?, @@ -644,7 +650,7 @@ impl<'t> Parser<'t> { const PARSING: Parsing = Parsing::TyTuple; Ok(TyTuple { types: delim( - sep(Self::ty, Punct::Comma, PARENS.1, PARSING), + sep(Self::tykind, Punct::Comma, PARENS.1, PARSING), PARENS, PARSING, )(self)?, @@ -668,19 +674,26 @@ impl<'t> Parser<'t> { pub fn tyfn(&mut self) -> PResult { const PARSING: Parsing = Parsing::TyFn; self.match_type(TokenKind::Fn, PARSING)?; + Ok(TyFn { - args: self.tytuple()?, - rety: { - match self.peek_kind(PARSING)? { - TokenKind::Punct(Punct::Arrow) => { - self.consume_peeked(); - Some(self.ty()?.into()) - } - _ => None, + args: Box::new(match self.tyfn_args()? { + t if t.is_empty() => TyKind::Empty, + types => TyKind::Tuple(TyTuple { types }), + }), + rety: match self.peek_kind(PARSING) { + Ok(TokenKind::Punct(Punct::Arrow)) => { + self.consume_peeked(); + Some(self.ty()?.into()) } + _ => None, }, }) } + + pub fn tyfn_args(&mut self) -> PResult> { + const P: Parsing = Parsing::TyFn; + delim(sep(Self::tykind, Punct::Comma, PARENS.1, P), PARENS, P)(self) + } } /// Expands to a pattern which matches literal-like [TokenKind]s