Skip to content

Commit f065b55

Browse files
committed
feat: make izip! temporary friendly
- some izip! calls with temporary values would not compile with the current izip! implementation due to the use of a block to create the temporary iter chain, if a user called izip! with an iterator from a temporary value the compilation would fail - this change adapts the macro to stop making use of the block and calls $crate::__std_iter::Iterator::zip directly to avoid the need for temporary iter bindings, this means the recursion produces a tuple of the form (a, (b, (c, d))) instead of (((a, b), c), d), needing a slight adaptation of the closure arm to invert the way arguments are unpacked, it also adds two arms to recursively build the zipped iterators without the final map adapter as we don't process all iterators at once as before
1 parent 9238090 commit f065b55

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

src/lib.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,27 @@ macro_rules! iproduct {
321321
macro_rules! izip {
322322
// @closure creates a tuple-flattening closure for .map() call. usage:
323323
// @closure partial_pattern => partial_tuple , rest , of , iterators
324-
// eg. izip!( @closure ((a, b), c) => (a, b, c) , dd , ee )
324+
// eg. izip!( @closure (a, (b, c)) => (a, b, c) , dd , ee )
325325
( @closure $p:pat => $tup:expr ) => {
326326
|$p| $tup
327327
};
328328

329329
// The "b" identifier is a different identifier on each recursion level thanks to hygiene.
330330
( @closure $p:pat => ( $($tup:tt)* ) , $_iter:expr $( , $tail:expr )* ) => {
331-
$crate::izip!(@closure ($p, b) => ( $($tup)*, b ) $( , $tail )*)
331+
$crate::izip!(@closure (b, $p) => ( b, $($tup)* ) $( , $tail )*)
332+
};
333+
334+
// Inner recursion of the macro without final map adapter, base case
335+
( @ no_map @ $first:expr $(,)?) => {
336+
$crate::__std_iter::IntoIterator::into_iter($first)
337+
};
338+
339+
// Inner recursion of the macro without final map adapter, recursive case
340+
( @ no_map @ $first:expr, $($rest:expr),+ $(,)?) => {
341+
$crate::__std_iter::Iterator::zip(
342+
$crate::__std_iter::IntoIterator::into_iter($first),
343+
$crate::izip!(@ no_map @ $($rest),+)
344+
)
332345
};
333346

334347
// unary
@@ -346,16 +359,13 @@ macro_rules! izip {
346359

347360
// n-ary where n > 2
348361
( $first:expr $( , $rest:expr )* $(,)* ) => {
349-
{
350-
let iter = $crate::__std_iter::IntoIterator::into_iter($first);
351-
$(
352-
let iter = $crate::__std_iter::Iterator::zip(iter, $rest);
353-
)*
354-
$crate::__std_iter::Iterator::map(
355-
iter,
356-
$crate::izip!(@closure a => (a) $( , $rest )*)
357-
)
358-
}
362+
$crate::__std_iter::Iterator::map(
363+
$crate::__std_iter::Iterator::zip(
364+
$crate::__std_iter::IntoIterator::into_iter($first),
365+
$crate::izip!(@ no_map @ $($rest),+)
366+
),
367+
$crate::izip!(@closure a => (a) $( , $rest )*)
368+
)
359369
};
360370
}
361371

0 commit comments

Comments
 (0)