diff --git a/src/func.rs b/src/func.rs index 2cdd026c2..33cc6e838 100644 --- a/src/func.rs +++ b/src/func.rs @@ -132,7 +132,7 @@ macro_rules! function { let func = $code; for arg in header.args.into_iter() { - feedback.errors.push(err!(arg.span(); "unexpected argument")); + feedback.errors.push(err!(arg.span; "unexpected argument")); } $crate::Pass::new(func, feedback) diff --git a/src/syntax/func/mod.rs b/src/syntax/func/mod.rs index 54d34531c..fd516208f 100644 --- a/src/syntax/func/mod.rs +++ b/src/syntax/func/mod.rs @@ -42,17 +42,22 @@ impl FuncArgs { } /// Add an argument. - pub fn add(&mut self, arg: FuncArg) { - match arg { - FuncArg::Pos(item) => self.pos.add(item), - FuncArg::Key(pair) => self.key.add(pair), + pub fn add(&mut self, arg: Spanned) { + match arg.v { + FuncArg::Pos(item) => self.pos.add(Spanned::new(item, arg.span)), + FuncArg::Key(pair) => self.key.add(Spanned::new(pair, arg.span)), } } /// Iterate over all arguments. - pub fn into_iter(self) -> impl Iterator { - self.pos.items.into_iter().map(|item| FuncArg::Pos(item)) - .chain(self.key.pairs.into_iter().map(|pair| FuncArg::Key(pair))) + pub fn into_iter(self) -> impl Iterator> { + let pos = self.pos.items.into_iter() + .map(|spanned| spanned.map(|item| FuncArg::Pos(item))); + + let key = self.key.pairs.into_iter() + .map(|spanned| spanned.map(|pair| FuncArg::Key(pair))); + + pos.chain(key) } } @@ -60,7 +65,7 @@ impl FromIterator> for FuncArgs { fn from_iter>>(iter: I) -> Self { let mut args = FuncArgs::new(); for item in iter.into_iter() { - args.add(item.v); + args.add(item); } args } @@ -70,22 +75,9 @@ impl FromIterator> for FuncArgs { #[derive(Debug, Clone, PartialEq)] pub enum FuncArg { /// A positional argument. - Pos(Spanned), + Pos(Expr), /// A keyword argument. - Key(Spanned), -} - -impl FuncArg { - /// The full span of this argument. - /// - /// In case of a positional argument this is just the span of the expression - /// and in case of a keyword argument the combined span of key and value. - pub fn span(&self) -> Span { - match self { - FuncArg::Pos(item) => item.span, - FuncArg::Key(item) => item.span, - } - } + Key(Pair), } /// Extra methods on [`Options`](Option) used for argument parsing. diff --git a/src/syntax/parsing.rs b/src/syntax/parsing.rs index 07dfec7cb..9636df210 100644 --- a/src/syntax/parsing.rs +++ b/src/syntax/parsing.rs @@ -190,10 +190,8 @@ impl<'s> FuncParser<'s> { if let Some(ident) = p.parse_ident() { // This could still be a named tuple if let Some(Token::LeftParen) = p.peekv() { - let n_tuple = p.parse_named_tuple(ident) - .map(|t| Expr::NamedTuple(t)); - let span = n_tuple.span; - return Ok(Spanned::new(FuncArg::Pos(n_tuple), span)); + let tuple = p.parse_named_tuple(ident); + return Ok(tuple.map(|t| FuncArg::Pos(Expr::NamedTuple(t)))); } p.skip_whitespace(); @@ -210,22 +208,18 @@ impl<'s> FuncParser<'s> { // Add a keyword argument. let span = Span::merge(ident.span, value.span); - Ok(Spanned::new( - FuncArg::Key(Spanned::new(Pair { key: ident, value }, span)), - span, - )) + let pair = Pair { key: ident, value }; + Ok(Spanned::new(FuncArg::Key(pair), span)) } else { // Add a positional argument because there was no equals // sign after the identifier that could have been a key. - let ident = ident.map(|id| Expr::Ident(id)); - let span = ident.span; - Ok(Spanned::new(FuncArg::Pos(ident), span)) + Ok(ident.map(|id| FuncArg::Pos(Expr::Ident(id)))) } } else { // Add a positional argument because we haven't got an // identifier that could be an argument key. - p.parse_expr().map(|expr| Spanned { span: expr.span, v: FuncArg::Pos(expr) }) - .ok_or(("argument", None)) + let value = p.parse_expr().ok_or(("argument", None))?; + Ok(value.map(|expr| FuncArg::Pos(expr))) } }).v }