diff options
-rw-r--r-- | .rustfmt.toml | 1 | ||||
-rw-r--r-- | dhall/build.rs | 12 | ||||
-rw-r--r-- | dhall/src/normalize.rs | 14 | ||||
-rw-r--r-- | dhall_core/src/parser.rs | 303 | ||||
-rw-r--r-- | dhall_generator/src/dhall_expr.rs | 3 | ||||
-rw-r--r-- | dhall_generator/src/dhall_type.rs | 3 | ||||
-rw-r--r-- | iter_patterns/src/lib.rs | 30 |
7 files changed, 263 insertions, 103 deletions
diff --git a/.rustfmt.toml b/.rustfmt.toml index 0c2ca5c..0713c39 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,2 +1,3 @@ edition = "2018" max_width = 80 +error_on_line_overflow = true diff --git a/dhall/build.rs b/dhall/build.rs index cc62a97..f7a31c0 100644 --- a/dhall/build.rs +++ b/dhall/build.rs @@ -36,12 +36,20 @@ fn main() -> std::io::Result<()> { if name == "largeExpression" { continue; } - writeln!(file, r#"make_spec_test!(ParserSuccess, spec_parser_success_{}, "{}");"#, name, path)?; + writeln!( + file, + r#"make_spec_test!(ParserSuccess, spec_parser_success_{}, "{}");"#, + name, path + )?; } for path in dhall_files_in_dir(&tests_dir.join("parser/failure/")) { let name = path.replace("/", "_"); - writeln!(file, r#"make_spec_test!(ParserFailure, spec_parser_failure_{}, "{}");"#, name, path)?; + writeln!( + file, + r#"make_spec_test!(ParserFailure, spec_parser_failure_{}, "{}");"#, + name, path + )?; } Ok(()) diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs index 1bf4b6a..a3a2318 100644 --- a/dhall/src/normalize.rs +++ b/dhall/src/normalize.rs @@ -104,7 +104,12 @@ where let a0 = Rc::clone(a0); let a1 = shift(1, &V("a".into(), 0), &a0); // TODO: use Embed to avoid reevaluating g - break dhall_expr!(g (List a0) (λ(a : a0) -> λ(as : List a1) -> [ a ] # as) ([] : List a0)); + break dhall_expr!( + g + (List a0) + (λ(a : a0) -> λ(as : List a1) -> [ a ] # as) + ([] : List a0) + ); } } (OptionalBuild, _, [a0, g, ..]) => { @@ -119,7 +124,12 @@ where }; let a0 = Rc::clone(a0); // TODO: use Embed to avoid reevaluating g - break dhall_expr!((g (Optional a0)) (λ(x: a0) -> Some x) (None a0)); + break dhall_expr!( + g + (Optional a0) + (λ(x: a0) -> Some x) + (None a0) + ); } } (ListFold, Some(EmptyListLit(_)), [_, _, _, _, nil, ..]) => { diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index fb119b1..99e1883 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -113,28 +113,83 @@ fn debug_pair(pair: Pair<Rule>) -> String { } macro_rules! match_pair { - (@make_child_match, ($pair:expr, $($vars:tt)*), ($($outer_acc:tt)*), ($($acc:tt)*), ($(,)* $ty:ident ($x:ident..) $($rest_of_match:tt)*) => $body:expr, $($rest:tt)*) => { - match_pair!(@make_child_match, ($pair, $($vars)*), ($($outer_acc)*), ($($acc)*, xs..), ($($rest_of_match)*) => { - let xs = xs.map(|x| match x { - ParsedValue::$ty(y) => Ok(y), - x => Err(format!("Unexpected child: {:?}", x)), - }).collect::<Result<Vec<_>, _>>()?; - let $x = xs.into_iter(); - $body - }, $($rest)*) + (@make_child_match, + ($pair:expr, $($vars:tt)*), + ($($outer_acc:tt)*), + ($($acc:tt)*), + ($(,)* $ty:ident ($x:ident..) $($rest_of_match:tt)*) => $body:expr, + $($rest:tt)* + ) => { + match_pair!(@make_child_match, + ($pair, $($vars)*), + ($($outer_acc)*), + ($($acc)*, xs..), + ($($rest_of_match)*) => { + let xs = xs.map(|x| match x { + ParsedValue::$ty(y) => Ok(y), + x => Err(format!("Unexpected child: {:?}", x)), + }).collect::<Result<Vec<_>, _>>()?; + let $x = xs.into_iter(); + $body + }, + $($rest)* + ) }; - (@make_child_match, ($($vars:tt)*), ($($outer_acc:tt)*), ($($acc:tt)*), ($(,)* $ty:ident ($x:pat) $($rest_of_match:tt)*) => $body:expr, $($rest:tt)*) => { - match_pair!(@make_child_match, ($($vars)*), ($($outer_acc)*), ($($acc)*, ParsedValue::$ty($x)), ($($rest_of_match)*) => $body, $($rest)*) + (@make_child_match, + ($($vars:tt)*), + ($($outer_acc:tt)*), + ($($acc:tt)*), + ($(,)* $ty:ident ($x:pat) $($rest_of_match:tt)*) => $body:expr, + $($rest:tt)* + ) => { + match_pair!(@make_child_match, + ($($vars)*), + ($($outer_acc)*), + ($($acc)*, ParsedValue::$ty($x)), + ($($rest_of_match)*) => $body, + $($rest)* + ) }; - (@make_child_match, ($($vars:tt)*), ($($outer_acc:tt)*), (, $($acc:tt)*), ($(,)*) => $body:expr, $($rest:tt)*) => { - match_pair!(@make_matches, ($($vars)*), ($($outer_acc)* [$($acc)*] => { $body },), $($rest)*) + (@make_child_match, + ($($vars:tt)*), + ($($outer_acc:tt)*), + (, $($acc:tt)*), + ($(,)*) => $body:expr, + $($rest:tt)* + ) => { + match_pair!(@make_matches, + ($($vars)*), + ($($outer_acc)* [$($acc)*] => { $body },), + $($rest)* + ) }; - (@make_child_match, ($($vars:tt)*), ($($outer_acc:tt)*), (), ($(,)*) => $body:expr, $($rest:tt)*) => { - match_pair!(@make_matches, ($($vars)*), ($($outer_acc)* [] => { $body },), $($rest)*) + (@make_child_match, + ($($vars:tt)*), + ($($outer_acc:tt)*), + (), + ($(,)*) => $body:expr, + $($rest:tt)* + ) => { + match_pair!(@make_matches, + ($($vars)*), + ($($outer_acc)* [] => { $body },), + $($rest)* + ) }; - (@make_matches, ($($vars:tt)*), ($($acc:tt)*), [$($args:tt)*] => $body:expr, $($rest:tt)*) => { - match_pair!(@make_child_match, ($($vars)*), ($($acc)*), (), ($($args)*) => $body, $($rest)*) + (@make_matches, + ($($vars:tt)*), + ($($acc:tt)*), + [$($args:tt)*] => $body:expr, + $($rest:tt)* + ) => { + match_pair!(@make_child_match, + ($($vars)*), + ($($acc)*), + (), + ($($args)*) => $body, + $($rest)* + ) }; (@make_matches, ($pair:expr, $children:expr), ($($acc:tt)*) $(,)*) => { { @@ -149,7 +204,11 @@ macro_rules! match_pair { }; (($($vars:tt)*); $( [$($args:tt)*] => $body:expr ),* $(,)*) => { - match_pair!(@make_matches, ($($vars)*), (), $( [$($args)*] => $body ),* ,) + match_pair!(@make_matches, + ($($vars)*), + (), + $( [$($args)*] => $body ),* , + ) }; } @@ -159,15 +218,39 @@ macro_rules! make_parser { (@filter, rule) => (true); (@filter, rule_group) => (false); - (@body, $pair:expr, $children:expr, rule!( $name:ident<$o:ty>; $($args:tt)* )) => ( - make_parser!(@body, $pair, $children, rule!( $name<$o> as $name; $($args)* )) + (@body, + $pair:expr, + $children:expr, + rule!( $name:ident<$o:ty>; $($args:tt)* ) + ) => ( + make_parser!(@body, + $pair, + $children, + rule!( $name<$o> as $name; $($args)* ) + ) ); - (@body, $pair:expr, $children:expr, rule!( $name:ident<$o:ty> as $group:ident; captured_str!($x:pat) => $body:expr )) => ( { + (@body, + $pair:expr, + $children:expr, + rule!( + $name:ident<$o:ty> + as $group:ident; + captured_str!($x:pat) => $body:expr + ) + ) => ({ let $x = $pair.as_str(); let res: $o = $body; Ok(ParsedValue::$group(res)) }); - (@body, $pair:expr, $children:expr, rule!( $name:ident<$o:ty> as $group:ident; children!( $($args:tt)* ) )) => ( { + (@body, + $pair:expr, + $children:expr, + rule!( + $name:ident<$o:ty> + as $group:ident; + children!( $($args:tt)* ) + ) + ) => ({ let res: $o = match_pair!(($pair, $children); $($args)*)?; Ok(ParsedValue::$group(res)) }); @@ -182,57 +265,60 @@ macro_rules! make_parser { $( $name($o), )* } - fn parse_any<'a>(pair: Pair<'a, Rule>, children: Vec<ParsedValue<'a>>) -> Result<ParsedValue<'a>, String> { + fn parse_any<'a>(pair: Pair<'a, Rule>, children: Vec<ParsedValue<'a>>) + -> Result<ParsedValue<'a>, String> { match pair.as_rule() { $( make_parser!(@pattern, $submac, $name) if make_parser!(@filter, $submac) - => make_parser!(@body, pair, children, $submac!( $name<$o> $($args)* )) + => make_parser!(@body, pair, children, + $submac!( $name<$o> $($args)* )) , )* r => Err(format!("Unexpected {:?}", r)), } } + ); +} - // Non-recursive implementation to avoid stack overflows - fn do_parse<'a>(initial_pair: Pair<'a, Rule>) -> ParseResult<ParsedValue<'a>> { - enum StackFrame<'a> { - Unprocessed(Pair<'a, Rule>), - Processed(Pair<'a, Rule>, usize), - } - use StackFrame::*; - let mut pairs_stack: Vec<StackFrame> = vec![Unprocessed(initial_pair.clone())]; - let mut values_stack: Vec<ParsedValue> = vec![]; - while let Some(p) = pairs_stack.pop() { - match p { - Unprocessed(mut pair) => { - loop { - let mut pairs: Vec<_> = pair.clone().into_inner().collect(); - let n_children = pairs.len(); - if n_children == 1 && can_be_shortcutted(pair.as_rule()) { - pair = pairs.pop().unwrap(); - continue - } else { - pairs_stack.push(Processed(pair, n_children)); - pairs_stack.extend(pairs.into_iter().map(StackFrame::Unprocessed)); - break - } - } - } - Processed(pair, n) => { - let mut children: Vec<_> = values_stack.split_off(values_stack.len() - n); - children.reverse(); - let val = match parse_any(pair.clone(), children) { - Ok(v) => v, - Err(msg) => Err(custom_parse_error(&pair, msg))?, - }; - values_stack.push(val); - } +// Non-recursive implementation to avoid stack overflows +fn do_parse<'a>(initial_pair: Pair<'a, Rule>) -> ParseResult<ParsedValue<'a>> { + enum StackFrame<'a> { + Unprocessed(Pair<'a, Rule>), + Processed(Pair<'a, Rule>, usize), + } + use StackFrame::*; + let mut pairs_stack: Vec<StackFrame> = + vec![Unprocessed(initial_pair.clone())]; + let mut values_stack: Vec<ParsedValue> = vec![]; + while let Some(p) = pairs_stack.pop() { + match p { + Unprocessed(mut pair) => loop { + let mut pairs: Vec<_> = pair.clone().into_inner().collect(); + let n_children = pairs.len(); + if n_children == 1 && can_be_shortcutted(pair.as_rule()) { + pair = pairs.pop().unwrap(); + continue; + } else { + pairs_stack.push(Processed(pair, n_children)); + pairs_stack + .extend(pairs.into_iter().map(StackFrame::Unprocessed)); + break; } + }, + Processed(pair, n) => { + let mut children: Vec<_> = + values_stack.split_off(values_stack.len() - n); + children.reverse(); + let val = match parse_any(pair.clone(), children) { + Ok(v) => v, + Err(msg) => Err(custom_parse_error(&pair, msg))?, + }; + values_stack.push(val); } - Ok(values_stack.pop().unwrap()) } - ); + } + Ok(values_stack.pop().unwrap()) } // List of rules that can be shortcutted if they have a single child @@ -261,8 +347,12 @@ fn can_be_shortcutted(rule: Rule) -> bool { make_parser! { rule!(EOI<()>; captured_str!(_) => ()); - rule!(simple_label<Label>; captured_str!(s) => Label::from(s.trim().to_owned())); - rule!(quoted_label<Label>; captured_str!(s) => Label::from(s.trim().to_owned())); + rule!(simple_label<Label>; + captured_str!(s) => Label::from(s.trim().to_owned()) + ); + rule!(quoted_label<Label>; + captured_str!(s) => Label::from(s.trim().to_owned()) + ); rule!(label<Label>; children!( [simple_label(l)] => l, [quoted_label(l)] => l, @@ -270,7 +360,9 @@ make_parser! { rule!(unreserved_label<Label>; children!( [label(l)] => { if Builtin::parse(&String::from(&l)).is_some() { - Err(format!("Builtin names are not allowed as bound variables"))? + Err( + format!("Builtin names are not allowed as bound variables") + )? } l }, @@ -514,8 +606,10 @@ make_parser! { ); rule!(import_hashed<ImportHashed>; children!( - [import_type(location)] => ImportHashed { location, hash: None }, - [import_type(location), hash(hash)] => ImportHashed { location, hash: Some(hash) }, + [import_type(location)] => + ImportHashed { location, hash: None }, + [import_type(location), hash(hash)] => + ImportHashed { location, hash: Some(hash) }, )); rule_group!(expression<ParsedExpr>); @@ -551,13 +645,18 @@ make_parser! { rule!(let_expression<ParsedExpr> as expression; children!( [let_binding(bindings..), expression(final_expr)] => { - bindings.fold(final_expr, |acc, x| bx(Expr::Let(x.0, x.1, x.2, acc))) + bindings.fold( + final_expr, + |acc, x| bx(Expr::Let(x.0, x.1, x.2, acc)) + ) } )); rule!(let_binding<(Label, Option<ParsedExpr>, ParsedExpr)>; children!( - [unreserved_label(name), expression(annot), expression(expr)] => (name, Some(annot), expr), - [unreserved_label(name), expression(expr)] => (name, None, expr), + [unreserved_label(name), expression(annot), expression(expr)] => + (name, Some(annot), expr), + [unreserved_label(name), expression(expr)] => + (name, None, expr), )); rule!(forall_expression<ParsedExpr> as expression; children!( @@ -573,8 +672,10 @@ make_parser! { )); rule!(merge_expression<ParsedExpr> as expression; children!( - [expression(x), expression(y), expression(z)] => bx(Expr::Merge(x, y, Some(z))), - [expression(x), expression(y)] => bx(Expr::Merge(x, y, None)), + [expression(x), expression(y), expression(z)] => + bx(Expr::Merge(x, y, Some(z))), + [expression(x), expression(y)] => + bx(Expr::Merge(x, y, None)), )); rule!(List<()>; captured_str!(_) => ()); @@ -598,73 +699,85 @@ make_parser! { rule!(import_alt_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::ImportAlt, acc, e))) + let o = BinOp::ImportAlt; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(or_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::BoolOr, acc, e))) + let o = BinOp::BoolOr; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(plus_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::NaturalPlus, acc, e))) + let o = BinOp::NaturalPlus; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(text_append_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::TextAppend, acc, e))) + let o = BinOp::TextAppend; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(list_append_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::ListAppend, acc, e))) + let o = BinOp::ListAppend; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(and_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::BoolAnd, acc, e))) + let o = BinOp::BoolAnd; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(combine_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::Combine, acc, e))) + let o = BinOp::Combine; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(prefer_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::Prefer, acc, e))) + let o = BinOp::Prefer; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(combine_types_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::CombineTypes, acc, e))) + let o = BinOp::CombineTypes; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(times_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::NaturalTimes, acc, e))) + let o = BinOp::NaturalTimes; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(equal_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::BoolEQ, acc, e))) + let o = BinOp::BoolEQ; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); rule!(not_equal_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest..)] => { - rest.fold(first, |acc, e| bx(Expr::BinOp(BinOp::BoolNE, acc, e))) + let o = BinOp::BoolNE; + rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) }, )); @@ -689,10 +802,15 @@ make_parser! { [expression(first), expression(second), expression(rest..)] => { match first.as_ref() { Expr::Builtin(Builtin::OptionalNone) => - bx(Expr::App(bx(Expr::EmptyOptionalLit(second)), rest.collect())), + bx(Expr::App(bx(Expr::EmptyOptionalLit(second)), + rest.collect())), Expr::Builtin(Builtin::OptionalSome) => - bx(Expr::App(bx(Expr::NEOptionalLit(second)), rest.collect())), - _ => bx(Expr::App(first, std::iter::once(second).chain(rest).collect())), + bx(Expr::App(bx(Expr::NEOptionalLit(second)), + rest.collect())), + _ => bx(Expr::App(first, + std::iter::once(second) + .chain(rest) + .collect())), } }, )); @@ -718,8 +836,10 @@ make_parser! { rule!(literal_expression<ParsedExpr> as expression; children!( [double_literal(n)] => bx(Expr::DoubleLit(n)), - [minus_infinity_literal(n)] => bx(Expr::DoubleLit(std::f64::NEG_INFINITY.into())), - [plus_infinity_literal(n)] => bx(Expr::DoubleLit(std::f64::INFINITY.into())), + [minus_infinity_literal(n)] => + bx(Expr::DoubleLit(std::f64::NEG_INFINITY.into())), + [plus_infinity_literal(n)] => + bx(Expr::DoubleLit(std::f64::INFINITY.into())), [NaN(n)] => bx(Expr::DoubleLit(std::f64::NAN.into())), [natural_literal(n)] => bx(Expr::NaturalLit(n)), [integer_literal(n)] => bx(Expr::IntegerLit(n)), @@ -778,7 +898,8 @@ make_parser! { }, )); - rule!(non_empty_record_type<(ParsedExpr, BTreeMap<Label, ParsedExpr>)>; children!( + rule!(non_empty_record_type + <(ParsedExpr, BTreeMap<Label, ParsedExpr>)>; children!( [expression(expr), record_type_entry(entries..)] => { (expr, entries.collect()) } @@ -788,7 +909,8 @@ make_parser! { [label(name), expression(expr)] => (name, expr) )); - rule!(non_empty_record_literal<(ParsedExpr, BTreeMap<Label, ParsedExpr>)>; children!( + rule!(non_empty_record_literal + <(ParsedExpr, BTreeMap<Label, ParsedExpr>)>; children!( [expression(expr), record_literal_entry(entries..)] => { (expr, entries.collect()) } @@ -813,7 +935,8 @@ make_parser! { rule!(empty_union_type<()>; captured_str!(_) => ()); rule!(non_empty_union_type_or_literal - <(Option<(Label, ParsedExpr)>, BTreeMap<Label, ParsedExpr>)>; children!( + <(Option<(Label, ParsedExpr)>, BTreeMap<Label, ParsedExpr>)>; + children!( [label(l), expression(e), union_type_entries(entries)] => { (Some((l, e)), entries) }, diff --git a/dhall_generator/src/dhall_expr.rs b/dhall_generator/src/dhall_expr.rs index bc9da22..41e558b 100644 --- a/dhall_generator/src/dhall_expr.rs +++ b/dhall_generator/src/dhall_expr.rs @@ -109,7 +109,8 @@ fn dhall_to_tokenstream_bx( // Non-free variable; interpolates as itself Some(()) => { let s: String = s.into(); - quote! { dhall_core::bx(dhall_core::Expr::Var(dhall_core::V(#s.into(), #n))) } + let var = quote! { dhall_core::V(#s.into(), #n) }; + bx(quote! { dhall_core::Expr::Var(#var) }) } // Free variable; interpolates as a rust variable None => { diff --git a/dhall_generator/src/dhall_type.rs b/dhall_generator/src/dhall_type.rs index 329cd79..42549bb 100644 --- a/dhall_generator/src/dhall_type.rs +++ b/dhall_generator/src/dhall_type.rs @@ -175,7 +175,8 @@ pub fn derive_dhall_type_inner( let ident = &input.ident; let tokens = quote! { - impl #impl_generics dhall::DhallType for #ident #ty_generics #where_clause { + impl #impl_generics dhall::DhallType for #ident #ty_generics + #where_clause { fn dhall_type() -> dhall_core::DhallExpr { #(#assertions)* #dhall_type diff --git a/iter_patterns/src/lib.rs b/iter_patterns/src/lib.rs index 5395755..10679aa 100644 --- a/iter_patterns/src/lib.rs +++ b/iter_patterns/src/lib.rs @@ -26,19 +26,31 @@ macro_rules! destructure_iter { // Variable length pattern (@match_forwards, $iter:expr, ($body:expr), $x:ident.., $($rest:tt)*) => { - $crate::destructure_iter!(@match_backwards, $iter, ({ - let $x = $iter; - $body - }), $($rest)*) + $crate::destructure_iter!(@match_backwards, + $iter, + ({ + let $x = $iter; + $body + }), + $($rest)* + ) }; // Variable length pattern without a binder (@match_forwards, $iter:expr, ($body:expr), .., $($rest:tt)*) => { - $crate::destructure_iter!(@match_backwards, $iter, ($body), $($rest)*) + $crate::destructure_iter!(@match_backwards, + $iter, + ($body), + $($rest)* + ) }; // Single item pattern (@match_forwards, $iter:expr, ($body:expr), $x:pat, $($rest:tt)*) => { if let Some($x) = $iter.next() { - $crate::destructure_iter!(@match_forwards, $iter, ($body), $($rest)*) + $crate::destructure_iter!(@match_forwards, + $iter, + ($body), + $($rest)* + ) } else { None } @@ -71,7 +83,11 @@ macro_rules! destructure_iter { { #[allow(unused_mut)] let mut iter = $iter; - $crate::destructure_iter!(@match_forwards, iter, (Some($body)), $($args)*,) + $crate::destructure_iter!(@match_forwards, + iter, + (Some($body)), + $($args)*, + ) } }; } |