From 39f27dd7b17cc22ce2b523eb7ddb2a646123e778 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Fri, 21 Feb 2025 18:28:02 +0100 Subject: [PATCH 1/9] Restore previous names for tuple collect specialization trait and default function for readability --- library/core/src/iter/traits/collect.rs | 56 ++++++++++++------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 97bb21c8a36e8..50faf078ba608 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -463,12 +463,12 @@ macro_rules! spec_tuple_impl { ( ( $ty_name:ident, $var_name:ident, $extend_ty_name: ident, - $trait_name:ident, $default_fn_name:ident, $cnt:tt + $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, $cnt:tt ), ) => { spec_tuple_impl!( - $trait_name, - $default_fn_name, + $SpecTupleExtendN, + $default_extend_tuple_n, #[doc(fake_variadic)] #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for \ 1- and 3- through 12-ary tuples were stabilized after 2-tuples, in \ @@ -479,12 +479,12 @@ macro_rules! spec_tuple_impl { ( ( $ty_name:ident, $var_name:ident, $extend_ty_name: ident, - $trait_name:ident, $default_fn_name:ident, $cnt:tt + $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, $cnt:tt ), $( ( $ty_names:ident, $var_names:ident, $extend_ty_names:ident, - $trait_names:ident, $default_fn_names:ident, $cnts:tt + $SpecTupleExtendNs:ident, $default_extend_tuple_ns:ident, $cnts:tt ), )* ) => { @@ -492,13 +492,13 @@ macro_rules! spec_tuple_impl { $( ( $ty_names, $var_names, $extend_ty_names, - $trait_names, $default_fn_names, $cnts + $SpecTupleExtendNs, $default_extend_tuple_ns, $cnts ), )* ); spec_tuple_impl!( - $trait_name, - $default_fn_name, + $SpecTupleExtendN, + $default_extend_tuple_n, #[doc(hidden)] => ( $ty_name, $var_name, $extend_ty_name, $cnt @@ -511,7 +511,7 @@ macro_rules! spec_tuple_impl { ); }; ( - $trait_name:ident, $default_fn_name:ident, #[$meta:meta] + $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, #[$meta:meta] $(#[$doctext:meta])? => $( ( $ty_names:ident, $var_names:ident, $extend_ty_names:ident, $cnts:tt @@ -549,7 +549,7 @@ macro_rules! spec_tuple_impl { fn extend>(&mut self, into_iter: T) { let ($($var_names,)*) = self; let iter = into_iter.into_iter(); - $trait_name::extend(iter, $($var_names,)*); + $SpecTupleExtendN::extend(iter, $($var_names,)*); } fn extend_one(&mut self, item: ($($ty_names,)*)) { @@ -568,11 +568,11 @@ macro_rules! spec_tuple_impl { } } - trait $trait_name<$($ty_names),*> { + trait $SpecTupleExtendN<$($ty_names),*> { fn extend(self, $($var_names: &mut $ty_names,)*); } - fn $default_fn_name<$($ty_names,)* $($extend_ty_names,)*>( + fn $default_extend_tuple_n<$($ty_names,)* $($extend_ty_names,)*>( iter: impl Iterator, $($var_names: &mut $extend_ty_names,)* ) where @@ -595,17 +595,17 @@ macro_rules! spec_tuple_impl { iter.fold((), extend($($var_names,)*)); } - impl<$($ty_names,)* $($extend_ty_names,)* Iter> $trait_name<$($extend_ty_names),*> for Iter + impl<$($ty_names,)* $($extend_ty_names,)* Iter> $SpecTupleExtendN<$($extend_ty_names),*> for Iter where $($extend_ty_names: Extend<$ty_names>,)* Iter: Iterator, { default fn extend(self, $($var_names: &mut $extend_ty_names),*) { - $default_fn_name(self, $($var_names),*); + $default_extend_tuple_n(self, $($var_names),*); } } - impl<$($ty_names,)* $($extend_ty_names,)* Iter> $trait_name<$($extend_ty_names),*> for Iter + impl<$($ty_names,)* $($extend_ty_names,)* Iter> $SpecTupleExtendN<$($extend_ty_names),*> for Iter where $($extend_ty_names: Extend<$ty_names>,)* Iter: TrustedLen, @@ -626,7 +626,7 @@ macro_rules! spec_tuple_impl { if upper_bound.is_none() { // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway. - $default_fn_name(self, $($var_names,)*); + $default_extend_tuple_n(self, $($var_names,)*); return; } @@ -677,16 +677,16 @@ macro_rules! spec_tuple_impl { } spec_tuple_impl!( - (L, l, EL, TraitL, default_extend_tuple_l, 11), - (K, k, EK, TraitK, default_extend_tuple_k, 10), - (J, j, EJ, TraitJ, default_extend_tuple_j, 9), - (I, i, EI, TraitI, default_extend_tuple_i, 8), - (H, h, EH, TraitH, default_extend_tuple_h, 7), - (G, g, EG, TraitG, default_extend_tuple_g, 6), - (F, f, EF, TraitF, default_extend_tuple_f, 5), - (E, e, EE, TraitE, default_extend_tuple_e, 4), - (D, d, ED, TraitD, default_extend_tuple_d, 3), - (C, c, EC, TraitC, default_extend_tuple_c, 2), - (B, b, EB, TraitB, default_extend_tuple_b, 1), - (A, a, EA, TraitA, default_extend_tuple_a, 0), + (L, l, EL, SpecTupleExtend12, default_extend_tuple_12, 11), + (K, k, EK, SpecTupleExtend11, default_extend_tuple_11, 10), + (J, j, EJ, SpecTupleExtend10, default_extend_tuple_10, 9), + (I, i, EI, SpecTupleExtend9, default_extend_tuple_9, 8), + (H, h, EH, SpecTupleExtend8, default_extend_tuple_8, 7), + (G, g, EG, SpecTupleExtend7, default_extend_tuple_7, 6), + (F, f, EF, SpecTupleExtend6, default_extend_tuple_6, 5), + (E, e, EE, SpecTupleExtend5, default_extend_tuple_5, 4), + (D, d, ED, SpecTupleExtend4, default_extend_tuple_4, 3), + (C, c, EC, SpecTupleExtend3, default_extend_tuple_3, 2), + (B, b, EB, SpecTupleExtend2, default_extend_tuple_2, 1), + (A, a, EA, SpecTupleExtend1, default_extend_tuple_1, 0), ); From 9e01c606e0b0d50b9e976d3bbffa063bd3fae633 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Fri, 21 Feb 2025 18:32:21 +0100 Subject: [PATCH 2/9] Restore previous names for tuple collect type params for readability --- library/core/src/iter/traits/collect.rs | 106 ++++++++++++------------ 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 50faf078ba608..a3b953538a511 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -462,7 +462,7 @@ impl Extend<()> for () { macro_rules! spec_tuple_impl { ( ( - $ty_name:ident, $var_name:ident, $extend_ty_name: ident, + $T:ident, $var_name:ident, $ExtendT: ident, $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, $cnt:tt ), ) => { @@ -473,17 +473,17 @@ macro_rules! spec_tuple_impl { #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for \ 1- and 3- through 12-ary tuples were stabilized after 2-tuples, in \ 1.85.0."] - => ($ty_name, $var_name, $extend_ty_name, $cnt), + => ($T, $var_name, $ExtendT, $cnt), ); }; ( ( - $ty_name:ident, $var_name:ident, $extend_ty_name: ident, + $T:ident, $var_name:ident, $ExtendT: ident, $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, $cnt:tt ), $( ( - $ty_names:ident, $var_names:ident, $extend_ty_names:ident, + $Ts:ident, $var_names:ident, $ExtendTs:ident, $SpecTupleExtendNs:ident, $default_extend_tuple_ns:ident, $cnts:tt ), )* @@ -491,7 +491,7 @@ macro_rules! spec_tuple_impl { spec_tuple_impl!( $( ( - $ty_names, $var_names, $extend_ty_names, + $Ts, $var_names, $ExtendTs, $SpecTupleExtendNs, $default_extend_tuple_ns, $cnts ), )* @@ -501,11 +501,11 @@ macro_rules! spec_tuple_impl { $default_extend_tuple_n, #[doc(hidden)] => ( - $ty_name, $var_name, $extend_ty_name, $cnt + $T, $var_name, $ExtendT, $cnt ), $( ( - $ty_names, $var_names, $extend_ty_names, $cnts + $Ts, $var_names, $ExtendTs, $cnts ), )* ); @@ -514,16 +514,16 @@ macro_rules! spec_tuple_impl { $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, #[$meta:meta] $(#[$doctext:meta])? => $( ( - $ty_names:ident, $var_names:ident, $extend_ty_names:ident, $cnts:tt + $Ts:ident, $var_names:ident, $ExtendTs:ident, $cnts:tt ), )* ) => { #[$meta] $(#[$doctext])? #[stable(feature = "extend_for_tuple", since = "1.56.0")] - impl<$($ty_names,)* $($extend_ty_names,)*> Extend<($($ty_names,)*)> for ($($extend_ty_names,)*) + impl<$($Ts,)* $($ExtendTs,)*> Extend<($($Ts,)*)> for ($($ExtendTs,)*) where - $($extend_ty_names: Extend<$ty_names>,)* + $($ExtendTs: Extend<$Ts>,)* { /// Allows to `extend` a tuple of collections that also implement `Extend`. /// @@ -546,13 +546,13 @@ macro_rules! spec_tuple_impl { /// assert_eq!(b, [2, 5, 8]); /// assert_eq!(c, [3, 6, 9]); /// ``` - fn extend>(&mut self, into_iter: T) { + fn extend>(&mut self, into_iter: T) { let ($($var_names,)*) = self; let iter = into_iter.into_iter(); $SpecTupleExtendN::extend(iter, $($var_names,)*); } - fn extend_one(&mut self, item: ($($ty_names,)*)) { + fn extend_one(&mut self, item: ($($Ts,)*)) { $(self.$cnts.extend_one(item.$cnts);)* } @@ -560,7 +560,7 @@ macro_rules! spec_tuple_impl { $(self.$cnts.extend_reserve(additional);)* } - unsafe fn extend_one_unchecked(&mut self, item: ($($ty_names,)*)) { + unsafe fn extend_one_unchecked(&mut self, item: ($($Ts,)*)) { // SAFETY: Those are our safety preconditions, and we correctly forward `extend_reserve`. unsafe { $(self.$cnts.extend_one_unchecked(item.$cnts);)* @@ -568,22 +568,22 @@ macro_rules! spec_tuple_impl { } } - trait $SpecTupleExtendN<$($ty_names),*> { - fn extend(self, $($var_names: &mut $ty_names,)*); + trait $SpecTupleExtendN<$($Ts),*> { + fn extend(self, $($var_names: &mut $Ts,)*); } - fn $default_extend_tuple_n<$($ty_names,)* $($extend_ty_names,)*>( - iter: impl Iterator, - $($var_names: &mut $extend_ty_names,)* + fn $default_extend_tuple_n<$($Ts,)* $($ExtendTs,)*>( + iter: impl Iterator, + $($var_names: &mut $ExtendTs,)* ) where - $($extend_ty_names: Extend<$ty_names>,)* + $($ExtendTs: Extend<$Ts>,)* { - fn extend<'a, $($ty_names,)*>( - $($var_names: &'a mut impl Extend<$ty_names>,)* - ) -> impl FnMut((), ($($ty_names,)*)) + 'a { + fn extend<'a, $($Ts,)*>( + $($var_names: &'a mut impl Extend<$Ts>,)* + ) -> impl FnMut((), ($($Ts,)*)) + 'a { #[allow(non_snake_case)] - move |(), ($($extend_ty_names,)*)| { - $($var_names.extend_one($extend_ty_names);)* + move |(), ($($ExtendTs,)*)| { + $($var_names.extend_one($ExtendTs);)* } } @@ -595,30 +595,30 @@ macro_rules! spec_tuple_impl { iter.fold((), extend($($var_names,)*)); } - impl<$($ty_names,)* $($extend_ty_names,)* Iter> $SpecTupleExtendN<$($extend_ty_names),*> for Iter + impl<$($Ts,)* $($ExtendTs,)* Iter> $SpecTupleExtendN<$($ExtendTs),*> for Iter where - $($extend_ty_names: Extend<$ty_names>,)* - Iter: Iterator, + $($ExtendTs: Extend<$Ts>,)* + Iter: Iterator, { - default fn extend(self, $($var_names: &mut $extend_ty_names),*) { + default fn extend(self, $($var_names: &mut $ExtendTs),*) { $default_extend_tuple_n(self, $($var_names),*); } } - impl<$($ty_names,)* $($extend_ty_names,)* Iter> $SpecTupleExtendN<$($extend_ty_names),*> for Iter + impl<$($Ts,)* $($ExtendTs,)* Iter> $SpecTupleExtendN<$($ExtendTs),*> for Iter where - $($extend_ty_names: Extend<$ty_names>,)* - Iter: TrustedLen, + $($ExtendTs: Extend<$Ts>,)* + Iter: TrustedLen, { - fn extend(self, $($var_names: &mut $extend_ty_names,)*) { - fn extend<'a, $($ty_names,)*>( - $($var_names: &'a mut impl Extend<$ty_names>,)* - ) -> impl FnMut((), ($($ty_names,)*)) + 'a { + fn extend(self, $($var_names: &mut $ExtendTs,)*) { + fn extend<'a, $($Ts,)*>( + $($var_names: &'a mut impl Extend<$Ts>,)* + ) -> impl FnMut((), ($($Ts,)*)) + 'a { #[allow(non_snake_case)] // SAFETY: We reserve enough space for the `size_hint`, and the iterator is // `TrustedLen` so its `size_hint` is exact. - move |(), ($($extend_ty_names,)*)| unsafe { - $($var_names.extend_one_unchecked($extend_ty_names);)* + move |(), ($($ExtendTs,)*)| unsafe { + $($var_names.extend_one_unchecked($ExtendTs);)* } } @@ -661,12 +661,12 @@ macro_rules! spec_tuple_impl { #[$meta] $(#[$doctext])? #[stable(feature = "from_iterator_for_tuple", since = "1.79.0")] - impl<$($ty_names,)* $($extend_ty_names,)*> FromIterator<($($extend_ty_names,)*)> for ($($ty_names,)*) + impl<$($Ts,)* $($ExtendTs,)*> FromIterator<($($ExtendTs,)*)> for ($($Ts,)*) where - $($ty_names: Default + Extend<$extend_ty_names>,)* + $($Ts: Default + Extend<$ExtendTs>,)* { - fn from_iter>(iter: Iter) -> Self { - let mut res = <($($ty_names,)*)>::default(); + fn from_iter>(iter: Iter) -> Self { + let mut res = <($($Ts,)*)>::default(); res.extend(iter); res @@ -677,16 +677,16 @@ macro_rules! spec_tuple_impl { } spec_tuple_impl!( - (L, l, EL, SpecTupleExtend12, default_extend_tuple_12, 11), - (K, k, EK, SpecTupleExtend11, default_extend_tuple_11, 10), - (J, j, EJ, SpecTupleExtend10, default_extend_tuple_10, 9), - (I, i, EI, SpecTupleExtend9, default_extend_tuple_9, 8), - (H, h, EH, SpecTupleExtend8, default_extend_tuple_8, 7), - (G, g, EG, SpecTupleExtend7, default_extend_tuple_7, 6), - (F, f, EF, SpecTupleExtend6, default_extend_tuple_6, 5), - (E, e, EE, SpecTupleExtend5, default_extend_tuple_5, 4), - (D, d, ED, SpecTupleExtend4, default_extend_tuple_4, 3), - (C, c, EC, SpecTupleExtend3, default_extend_tuple_3, 2), - (B, b, EB, SpecTupleExtend2, default_extend_tuple_2, 1), - (A, a, EA, SpecTupleExtend1, default_extend_tuple_1, 0), + (L, l, ExtendL, SpecTupleExtend12, default_extend_tuple_12, 11), + (K, k, ExtendK, SpecTupleExtend11, default_extend_tuple_11, 10), + (J, j, ExtendJ, SpecTupleExtend10, default_extend_tuple_10, 9), + (I, i, ExtendI, SpecTupleExtend9, default_extend_tuple_9, 8), + (H, h, ExtendH, SpecTupleExtend8, default_extend_tuple_8, 7), + (G, g, ExtendG, SpecTupleExtend7, default_extend_tuple_7, 6), + (F, f, ExtendF, SpecTupleExtend6, default_extend_tuple_6, 5), + (E, e, ExtendE, SpecTupleExtend5, default_extend_tuple_5, 4), + (D, d, ExtendD, SpecTupleExtend4, default_extend_tuple_4, 3), + (C, c, ExtendC, SpecTupleExtend3, default_extend_tuple_3, 2), + (B, b, ExtendB, SpecTupleExtend2, default_extend_tuple_2, 1), + (A, a, ExtendA, SpecTupleExtend1, default_extend_tuple_1, 0), ); From 29bef947bd188a5206a67706729b3dc922216d91 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Fri, 21 Feb 2025 20:26:08 +0100 Subject: [PATCH 3/9] Get Extend for tuples (back) into the correct order of operations & params --- library/core/src/iter/traits/collect.rs | 78 ++++++++++++------------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index a3b953538a511..5332104ad9893 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -461,10 +461,27 @@ impl Extend<()> for () { macro_rules! spec_tuple_impl { ( + [$($params_:tt)*] ( - $T:ident, $var_name:ident, $ExtendT: ident, - $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, $cnt:tt + $params:tt, $SpecTupleExtendN:ident, $default_extend_tuple_n:ident ), + $($remainder:tt,)* + ) => { + spec_tuple_impl!( + $SpecTupleExtendN, + $default_extend_tuple_n, + $($params_,)* + $params + ); + spec_tuple_impl!( + [$($params_)* $params] + $($remainder,)* + ); + }; + ([$($params_:tt)*]) => {}; + ( + $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, + $params:tt ) => { spec_tuple_impl!( $SpecTupleExtendN, @@ -473,41 +490,18 @@ macro_rules! spec_tuple_impl { #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for \ 1- and 3- through 12-ary tuples were stabilized after 2-tuples, in \ 1.85.0."] - => ($T, $var_name, $ExtendT, $cnt), + => $params, ); }; ( - ( - $T:ident, $var_name:ident, $ExtendT: ident, - $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, $cnt:tt - ), - $( - ( - $Ts:ident, $var_names:ident, $ExtendTs:ident, - $SpecTupleExtendNs:ident, $default_extend_tuple_ns:ident, $cnts:tt - ), - )* + $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, + $($params:tt),+ ) => { - spec_tuple_impl!( - $( - ( - $Ts, $var_names, $ExtendTs, - $SpecTupleExtendNs, $default_extend_tuple_ns, $cnts - ), - )* - ); spec_tuple_impl!( $SpecTupleExtendN, $default_extend_tuple_n, #[doc(hidden)] - => ( - $T, $var_name, $ExtendT, $cnt - ), - $( - ( - $Ts, $var_names, $ExtendTs, $cnts - ), - )* + => $($params,)+ ); }; ( @@ -676,17 +670,17 @@ macro_rules! spec_tuple_impl { }; } -spec_tuple_impl!( - (L, l, ExtendL, SpecTupleExtend12, default_extend_tuple_12, 11), - (K, k, ExtendK, SpecTupleExtend11, default_extend_tuple_11, 10), - (J, j, ExtendJ, SpecTupleExtend10, default_extend_tuple_10, 9), - (I, i, ExtendI, SpecTupleExtend9, default_extend_tuple_9, 8), - (H, h, ExtendH, SpecTupleExtend8, default_extend_tuple_8, 7), - (G, g, ExtendG, SpecTupleExtend7, default_extend_tuple_7, 6), - (F, f, ExtendF, SpecTupleExtend6, default_extend_tuple_6, 5), - (E, e, ExtendE, SpecTupleExtend5, default_extend_tuple_5, 4), - (D, d, ExtendD, SpecTupleExtend4, default_extend_tuple_4, 3), - (C, c, ExtendC, SpecTupleExtend3, default_extend_tuple_3, 2), - (B, b, ExtendB, SpecTupleExtend2, default_extend_tuple_2, 1), - (A, a, ExtendA, SpecTupleExtend1, default_extend_tuple_1, 0), +spec_tuple_impl!([] + ((A, a, ExtendA, 0), SpecTupleExtend1, default_extend_tuple_1), + ((B, b, ExtendB, 1), SpecTupleExtend2, default_extend_tuple_2), + ((C, c, ExtendC, 2), SpecTupleExtend3, default_extend_tuple_3), + ((D, d, ExtendD, 3), SpecTupleExtend4, default_extend_tuple_4), + ((E, e, ExtendE, 4), SpecTupleExtend5, default_extend_tuple_5), + ((F, f, ExtendF, 5), SpecTupleExtend6, default_extend_tuple_6), + ((G, g, ExtendG, 6), SpecTupleExtend7, default_extend_tuple_7), + ((H, h, ExtendH, 7), SpecTupleExtend8, default_extend_tuple_8), + ((I, i, ExtendI, 8), SpecTupleExtend9, default_extend_tuple_9), + ((J, j, ExtendJ, 9), SpecTupleExtend10, default_extend_tuple_10), + ((K, k, ExtendK, 10), SpecTupleExtend11, default_extend_tuple_11), + ((L, l, ExtendL, 11), SpecTupleExtend12, default_extend_tuple_12), ); From 75b23cf80da4bc736d9a39b62d7cf00ff1bfff78 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Fri, 21 Feb 2025 20:44:56 +0100 Subject: [PATCH 4/9] Change to usual T, U, V, ... naming --- library/core/src/iter/traits/collect.rs | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 5332104ad9893..0519f0852e55c 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -540,7 +540,7 @@ macro_rules! spec_tuple_impl { /// assert_eq!(b, [2, 5, 8]); /// assert_eq!(c, [3, 6, 9]); /// ``` - fn extend>(&mut self, into_iter: T) { + fn extend>(&mut self, into_iter: I) { let ($($var_names,)*) = self; let iter = into_iter.into_iter(); $SpecTupleExtendN::extend(iter, $($var_names,)*); @@ -671,16 +671,16 @@ macro_rules! spec_tuple_impl { } spec_tuple_impl!([] - ((A, a, ExtendA, 0), SpecTupleExtend1, default_extend_tuple_1), - ((B, b, ExtendB, 1), SpecTupleExtend2, default_extend_tuple_2), - ((C, c, ExtendC, 2), SpecTupleExtend3, default_extend_tuple_3), - ((D, d, ExtendD, 3), SpecTupleExtend4, default_extend_tuple_4), - ((E, e, ExtendE, 4), SpecTupleExtend5, default_extend_tuple_5), - ((F, f, ExtendF, 5), SpecTupleExtend6, default_extend_tuple_6), - ((G, g, ExtendG, 6), SpecTupleExtend7, default_extend_tuple_7), - ((H, h, ExtendH, 7), SpecTupleExtend8, default_extend_tuple_8), - ((I, i, ExtendI, 8), SpecTupleExtend9, default_extend_tuple_9), - ((J, j, ExtendJ, 9), SpecTupleExtend10, default_extend_tuple_10), - ((K, k, ExtendK, 10), SpecTupleExtend11, default_extend_tuple_11), - ((L, l, ExtendL, 11), SpecTupleExtend12, default_extend_tuple_12), + ((T, t, ExtendT, 0), SpecTupleExtend1, default_extend_tuple_1), + ((U, u, ExtendU, 1), SpecTupleExtend2, default_extend_tuple_2), + ((V, v, ExtendV, 2), SpecTupleExtend3, default_extend_tuple_3), + ((X, x, ExtendX, 3), SpecTupleExtend4, default_extend_tuple_4), + ((Y, y, ExtendY, 4), SpecTupleExtend5, default_extend_tuple_5), + ((Z, z, ExtendZ, 5), SpecTupleExtend6, default_extend_tuple_6), + ((A, a, ExtendA, 6), SpecTupleExtend7, default_extend_tuple_7), + ((B, b, ExtendB, 7), SpecTupleExtend8, default_extend_tuple_8), + ((C, c, ExtendC, 8), SpecTupleExtend9, default_extend_tuple_9), + ((D, d, ExtendD, 9), SpecTupleExtend10, default_extend_tuple_10), + ((E, e, ExtendE, 10), SpecTupleExtend11, default_extend_tuple_11), + ((F, f, ExtendF, 11), SpecTupleExtend12, default_extend_tuple_12), ); From 2de5709aca78ec68f765eb869bdad8d9c9239540 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Fri, 21 Feb 2025 21:03:29 +0100 Subject: [PATCH 5/9] Special impl for 1-tuple, more efficient by simple delegation to field's extend impl --- library/core/src/iter/traits/collect.rs | 194 ++++++++++++++---------- 1 file changed, 111 insertions(+), 83 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 0519f0852e55c..be0a4b3e63ff3 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -478,7 +478,7 @@ macro_rules! spec_tuple_impl { $($remainder,)* ); }; - ([$($params_:tt)*]) => {}; + ( [$($params_:tt)*] ) => { }; ( $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, $params:tt @@ -486,6 +486,7 @@ macro_rules! spec_tuple_impl { spec_tuple_impl!( $SpecTupleExtendN, $default_extend_tuple_n, + #special_case_1_tuple #[doc(fake_variadic)] #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for \ 1- and 3- through 12-ary tuples were stabilized after 2-tuples, in \ @@ -500,12 +501,14 @@ macro_rules! spec_tuple_impl { spec_tuple_impl!( $SpecTupleExtendN, $default_extend_tuple_n, + #normal_case #[doc(hidden)] => $($params,)+ ); }; ( - $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, #[$meta:meta] + $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, #$maybe_special_case:tt + #[$meta:meta] $(#[$doctext:meta])? => $( ( $Ts:ident, $var_names:ident, $ExtendTs:ident, $cnts:tt @@ -519,32 +522,15 @@ macro_rules! spec_tuple_impl { where $($ExtendTs: Extend<$Ts>,)* { - /// Allows to `extend` a tuple of collections that also implement `Extend`. - /// - /// See also: [`Iterator::unzip`] - /// - /// # Examples - /// ``` - /// // Example given for a 2-tuple, but 1- through 12-tuples are supported - /// let mut tuple = (vec![0], vec![1]); - /// tuple.extend([(2, 3), (4, 5), (6, 7)]); - /// assert_eq!(tuple.0, [0, 2, 4, 6]); - /// assert_eq!(tuple.1, [1, 3, 5, 7]); - /// - /// // also allows for arbitrarily nested tuples as elements - /// let mut nested_tuple = (vec![1], (vec![2], vec![3])); - /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]); - /// - /// let (a, (b, c)) = nested_tuple; - /// assert_eq!(a, [1, 4, 7]); - /// assert_eq!(b, [2, 5, 8]); - /// assert_eq!(c, [3, 6, 9]); - /// ``` - fn extend>(&mut self, into_iter: I) { - let ($($var_names,)*) = self; - let iter = into_iter.into_iter(); - $SpecTupleExtendN::extend(iter, $($var_names,)*); - } + + spec_tuple_impl!(#$maybe_special_case + + fn extend>(&mut self, into_iter: I) { + let ($($var_names,)*) = self; + let iter = into_iter.into_iter(); + $SpecTupleExtendN::extend(iter, $($var_names,)*); + } + ); fn extend_one(&mut self, item: ($($Ts,)*)) { $(self.$cnts.extend_one(item.$cnts);)* @@ -562,75 +548,78 @@ macro_rules! spec_tuple_impl { } } - trait $SpecTupleExtendN<$($Ts),*> { - fn extend(self, $($var_names: &mut $Ts,)*); - } + spec_tuple_impl!(#$maybe_special_case - fn $default_extend_tuple_n<$($Ts,)* $($ExtendTs,)*>( - iter: impl Iterator, - $($var_names: &mut $ExtendTs,)* - ) where - $($ExtendTs: Extend<$Ts>,)* - { - fn extend<'a, $($Ts,)*>( - $($var_names: &'a mut impl Extend<$Ts>,)* - ) -> impl FnMut((), ($($Ts,)*)) + 'a { - #[allow(non_snake_case)] - move |(), ($($ExtendTs,)*)| { - $($var_names.extend_one($ExtendTs);)* - } + trait $SpecTupleExtendN<$($Ts),*> { + fn extend(self, $($var_names: &mut $Ts,)*); } - let (lower_bound, _) = iter.size_hint(); - if lower_bound > 0 { - $($var_names.extend_reserve(lower_bound);)* - } - - iter.fold((), extend($($var_names,)*)); - } - - impl<$($Ts,)* $($ExtendTs,)* Iter> $SpecTupleExtendN<$($ExtendTs),*> for Iter - where - $($ExtendTs: Extend<$Ts>,)* - Iter: Iterator, - { - default fn extend(self, $($var_names: &mut $ExtendTs),*) { - $default_extend_tuple_n(self, $($var_names),*); - } - } - - impl<$($Ts,)* $($ExtendTs,)* Iter> $SpecTupleExtendN<$($ExtendTs),*> for Iter - where - $($ExtendTs: Extend<$Ts>,)* - Iter: TrustedLen, - { - fn extend(self, $($var_names: &mut $ExtendTs,)*) { + fn $default_extend_tuple_n<$($Ts,)* $($ExtendTs,)*>( + iter: impl Iterator, + $($var_names: &mut $ExtendTs,)* + ) where + $($ExtendTs: Extend<$Ts>,)* + { fn extend<'a, $($Ts,)*>( $($var_names: &'a mut impl Extend<$Ts>,)* ) -> impl FnMut((), ($($Ts,)*)) + 'a { #[allow(non_snake_case)] - // SAFETY: We reserve enough space for the `size_hint`, and the iterator is - // `TrustedLen` so its `size_hint` is exact. - move |(), ($($ExtendTs,)*)| unsafe { - $($var_names.extend_one_unchecked($ExtendTs);)* + move |(), ($($ExtendTs,)*)| { + $($var_names.extend_one($ExtendTs);)* } } - let (lower_bound, upper_bound) = self.size_hint(); - - if upper_bound.is_none() { - // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway. - $default_extend_tuple_n(self, $($var_names,)*); - return; - } - + let (lower_bound, _) = iter.size_hint(); if lower_bound > 0 { $($var_names.extend_reserve(lower_bound);)* } - self.fold((), extend($($var_names,)*)); + iter.fold((), extend($($var_names,)*)); } - } + + impl<$($Ts,)* $($ExtendTs,)* Iter> $SpecTupleExtendN<$($ExtendTs),*> for Iter + where + $($ExtendTs: Extend<$Ts>,)* + Iter: Iterator, + { + default fn extend(self, $($var_names: &mut $ExtendTs),*) { + $default_extend_tuple_n(self, $($var_names),*); + } + } + + impl<$($Ts,)* $($ExtendTs,)* Iter> $SpecTupleExtendN<$($ExtendTs),*> for Iter + where + $($ExtendTs: Extend<$Ts>,)* + Iter: TrustedLen, + { + fn extend(self, $($var_names: &mut $ExtendTs,)*) { + fn extend<'a, $($Ts,)*>( + $($var_names: &'a mut impl Extend<$Ts>,)* + ) -> impl FnMut((), ($($Ts,)*)) + 'a { + #[allow(non_snake_case)] + // SAFETY: We reserve enough space for the `size_hint`, and the iterator is + // `TrustedLen` so its `size_hint` is exact. + move |(), ($($ExtendTs,)*)| unsafe { + $($var_names.extend_one_unchecked($ExtendTs);)* + } + } + + let (lower_bound, upper_bound) = self.size_hint(); + + if upper_bound.is_none() { + // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway. + $default_extend_tuple_n(self, $($var_names,)*); + return; + } + + if lower_bound > 0 { + $($var_names.extend_reserve(lower_bound);)* + } + + self.fold((), extend($($var_names,)*)); + } + } + ); /// This implementation turns an iterator of tuples into a tuple of types which implement /// [`Default`] and [`Extend`]. @@ -666,7 +655,46 @@ macro_rules! spec_tuple_impl { res } } - + }; + ( + #special_case_1_tuple fn + $($t:tt)* + ) => { + /// Allows to `extend` a tuple of collections that also implement `Extend`. + /// + /// See also: [`Iterator::unzip`] + /// + /// # Examples + /// ``` + /// // Example given for a 2-tuple, but 1- through 12-tuples are supported + /// let mut tuple = (vec![0], vec![1]); + /// tuple.extend([(2, 3), (4, 5), (6, 7)]); + /// assert_eq!(tuple.0, [0, 2, 4, 6]); + /// assert_eq!(tuple.1, [1, 3, 5, 7]); + /// + /// // also allows for arbitrarily nested tuples as elements + /// let mut nested_tuple = (vec![1], (vec![2], vec![3])); + /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]); + /// + /// let (a, (b, c)) = nested_tuple; + /// assert_eq!(a, [1, 4, 7]); + /// assert_eq!(b, [2, 5, 8]); + /// assert_eq!(c, [3, 6, 9]); + /// ``` + fn extend>(&mut self, into_iter: I) { + self.0.extend(into_iter.into_iter().map(|(a,)| a)); + } + }; + ( + #special_case_1_tuple $($t:tt)* + ) => { + // no specialization traits + }; + ( + #normal_case + $($t:tt)* + ) => { + $($t)* }; } From aadda55dcdc30353acdef4d4583ae6ab4c7674b4 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Fri, 21 Feb 2025 21:05:36 +0100 Subject: [PATCH 6/9] Add comma for better rustfmt result --- library/core/src/iter/traits/collect.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index be0a4b3e63ff3..816e00feaeb97 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -461,7 +461,7 @@ impl Extend<()> for () { macro_rules! spec_tuple_impl { ( - [$($params_:tt)*] + [$($params_:tt)*], ( $params:tt, $SpecTupleExtendN:ident, $default_extend_tuple_n:ident ), @@ -474,11 +474,11 @@ macro_rules! spec_tuple_impl { $params ); spec_tuple_impl!( - [$($params_)* $params] + [$($params_)* $params], $($remainder,)* ); }; - ( [$($params_:tt)*] ) => { }; + ( [$($params_:tt)*], ) => { }; ( $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, $params:tt @@ -698,7 +698,8 @@ macro_rules! spec_tuple_impl { }; } -spec_tuple_impl!([] +spec_tuple_impl!( + [], ((T, t, ExtendT, 0), SpecTupleExtend1, default_extend_tuple_1), ((U, u, ExtendU, 1), SpecTupleExtend2, default_extend_tuple_2), ((V, v, ExtendV, 2), SpecTupleExtend3, default_extend_tuple_3), From 37e531a3f15a1f644419bcf69145ac91e9c10271 Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Fri, 21 Feb 2025 21:24:29 +0100 Subject: [PATCH 7/9] Final touchups --- library/core/src/iter/traits/collect.rs | 105 ++++++++++++------------ 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 816e00feaeb97..c955544b9a02f 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -463,7 +463,7 @@ macro_rules! spec_tuple_impl { ( [$($params_:tt)*], ( - $params:tt, $SpecTupleExtendN:ident, $default_extend_tuple_n:ident + $params:tt, $SpecTupleExtendN:tt, $default_extend_tuple_n:tt ), $($remainder:tt,)* ) => { @@ -480,7 +480,7 @@ macro_rules! spec_tuple_impl { }; ( [$($params_:tt)*], ) => { }; ( - $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, + $SpecTupleExtendN:tt, $default_extend_tuple_n:tt, $params:tt ) => { spec_tuple_impl!( @@ -495,7 +495,7 @@ macro_rules! spec_tuple_impl { ); }; ( - $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, + $SpecTupleExtendN:tt, $default_extend_tuple_n:tt, $($params:tt),+ ) => { spec_tuple_impl!( @@ -507,65 +507,66 @@ macro_rules! spec_tuple_impl { ); }; ( - $SpecTupleExtendN:ident, $default_extend_tuple_n:ident, #$maybe_special_case:tt + $SpecTupleExtendN:tt, $default_extend_tuple_n:tt, + #$skip_specialization_trait_for_1_tuple:tt #[$meta:meta] $(#[$doctext:meta])? => $( ( - $Ts:ident, $var_names:ident, $ExtendTs:ident, $cnts:tt + $T:ident, $var_names:ident, $ExtendT:ident, $cnt:tt ), )* ) => { #[$meta] $(#[$doctext])? #[stable(feature = "extend_for_tuple", since = "1.56.0")] - impl<$($Ts,)* $($ExtendTs,)*> Extend<($($Ts,)*)> for ($($ExtendTs,)*) + impl<$($T,)* $($ExtendT,)*> Extend<($($T,)*)> for ($($ExtendT,)*) where - $($ExtendTs: Extend<$Ts>,)* + $($ExtendT: Extend<$T>,)* { + spec_tuple_impl!( + #$skip_specialization_trait_for_1_tuple - spec_tuple_impl!(#$maybe_special_case - - fn extend>(&mut self, into_iter: I) { + fn extend>(&mut self, into_iter: I) { let ($($var_names,)*) = self; let iter = into_iter.into_iter(); $SpecTupleExtendN::extend(iter, $($var_names,)*); } ); - fn extend_one(&mut self, item: ($($Ts,)*)) { - $(self.$cnts.extend_one(item.$cnts);)* + fn extend_one(&mut self, item: ($($T,)*)) { + $(self.$cnt.extend_one(item.$cnt);)* } fn extend_reserve(&mut self, additional: usize) { - $(self.$cnts.extend_reserve(additional);)* + $(self.$cnt.extend_reserve(additional);)* } - unsafe fn extend_one_unchecked(&mut self, item: ($($Ts,)*)) { + unsafe fn extend_one_unchecked(&mut self, item: ($($T,)*)) { // SAFETY: Those are our safety preconditions, and we correctly forward `extend_reserve`. unsafe { - $(self.$cnts.extend_one_unchecked(item.$cnts);)* + $(self.$cnt.extend_one_unchecked(item.$cnt);)* } } } - spec_tuple_impl!(#$maybe_special_case + spec_tuple_impl!( + #$skip_specialization_trait_for_1_tuple - trait $SpecTupleExtendN<$($Ts),*> { - fn extend(self, $($var_names: &mut $Ts,)*); + trait $SpecTupleExtendN<$($T),*> { + fn extend(self, $($var_names: &mut $T,)*); } - fn $default_extend_tuple_n<$($Ts,)* $($ExtendTs,)*>( - iter: impl Iterator, - $($var_names: &mut $ExtendTs,)* + fn $default_extend_tuple_n<$($T,)* $($ExtendT,)*>( + iter: impl Iterator, + $($var_names: &mut $ExtendT,)* ) where - $($ExtendTs: Extend<$Ts>,)* + $($ExtendT: Extend<$T>,)* { - fn extend<'a, $($Ts,)*>( - $($var_names: &'a mut impl Extend<$Ts>,)* - ) -> impl FnMut((), ($($Ts,)*)) + 'a { - #[allow(non_snake_case)] - move |(), ($($ExtendTs,)*)| { - $($var_names.extend_one($ExtendTs);)* + fn extend<'a, $($T,)*>( + $($var_names: &'a mut impl Extend<$T>,)* + ) -> impl FnMut((), ($($T,)*)) + 'a { + move |(), item| { + $($var_names.extend_one(item.$cnt);)* } } @@ -577,30 +578,29 @@ macro_rules! spec_tuple_impl { iter.fold((), extend($($var_names,)*)); } - impl<$($Ts,)* $($ExtendTs,)* Iter> $SpecTupleExtendN<$($ExtendTs),*> for Iter + impl<$($T,)* $($ExtendT,)* Iter> $SpecTupleExtendN<$($ExtendT),*> for Iter where - $($ExtendTs: Extend<$Ts>,)* - Iter: Iterator, + $($ExtendT: Extend<$T>,)* + Iter: Iterator, { - default fn extend(self, $($var_names: &mut $ExtendTs),*) { + default fn extend(self, $($var_names: &mut $ExtendT),*) { $default_extend_tuple_n(self, $($var_names),*); } } - impl<$($Ts,)* $($ExtendTs,)* Iter> $SpecTupleExtendN<$($ExtendTs),*> for Iter + impl<$($T,)* $($ExtendT,)* Iter> $SpecTupleExtendN<$($ExtendT),*> for Iter where - $($ExtendTs: Extend<$Ts>,)* - Iter: TrustedLen, + $($ExtendT: Extend<$T>,)* + Iter: TrustedLen, { - fn extend(self, $($var_names: &mut $ExtendTs,)*) { - fn extend<'a, $($Ts,)*>( - $($var_names: &'a mut impl Extend<$Ts>,)* - ) -> impl FnMut((), ($($Ts,)*)) + 'a { - #[allow(non_snake_case)] + fn extend(self, $($var_names: &mut $ExtendT,)*) { + fn extend<'a, $($T,)*>( + $($var_names: &'a mut impl Extend<$T>,)* + ) -> impl FnMut((), ($($T,)*)) + 'a { // SAFETY: We reserve enough space for the `size_hint`, and the iterator is // `TrustedLen` so its `size_hint` is exact. - move |(), ($($ExtendTs,)*)| unsafe { - $($var_names.extend_one_unchecked($ExtendTs);)* + move |(), item| unsafe { + $($var_names.extend_one_unchecked(item.$cnt);)* } } @@ -644,12 +644,12 @@ macro_rules! spec_tuple_impl { #[$meta] $(#[$doctext])? #[stable(feature = "from_iterator_for_tuple", since = "1.79.0")] - impl<$($Ts,)* $($ExtendTs,)*> FromIterator<($($ExtendTs,)*)> for ($($Ts,)*) + impl<$($T,)* $($ExtendT,)*> FromIterator<($($ExtendT,)*)> for ($($T,)*) where - $($Ts: Default + Extend<$ExtendTs>,)* + $($T: Default + Extend<$ExtendT>,)* { - fn from_iter>(iter: Iter) -> Self { - let mut res = <($($Ts,)*)>::default(); + fn from_iter>(iter: Iter) -> Self { + let mut res = <($($T,)*)>::default(); res.extend(iter); res @@ -657,8 +657,8 @@ macro_rules! spec_tuple_impl { } }; ( - #special_case_1_tuple fn - $($t:tt)* + #special_case_1_tuple + fn $($t:tt)* ) => { /// Allows to `extend` a tuple of collections that also implement `Extend`. /// @@ -681,12 +681,13 @@ macro_rules! spec_tuple_impl { /// assert_eq!(b, [2, 5, 8]); /// assert_eq!(c, [3, 6, 9]); /// ``` - fn extend>(&mut self, into_iter: I) { - self.0.extend(into_iter.into_iter().map(|(a,)| a)); + fn extend>(&mut self, iter: I) { + self.0.extend(iter.into_iter().map(|(a,)| a)); } }; ( - #special_case_1_tuple $($t:tt)* + #special_case_1_tuple + $($t:tt)* ) => { // no specialization traits }; @@ -700,7 +701,7 @@ macro_rules! spec_tuple_impl { spec_tuple_impl!( [], - ((T, t, ExtendT, 0), SpecTupleExtend1, default_extend_tuple_1), + ((T, t, ExtendT, 0), @, @), ((U, u, ExtendU, 1), SpecTupleExtend2, default_extend_tuple_2), ((V, v, ExtendV, 2), SpecTupleExtend3, default_extend_tuple_3), ((X, x, ExtendX, 3), SpecTupleExtend4, default_extend_tuple_4), From 2b50f110e322584eef66eab8c21e82d650b73f7b Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Fri, 21 Feb 2025 21:27:31 +0100 Subject: [PATCH 8/9] Fix accidental skip of w in T U V.. naming --- library/core/src/iter/traits/collect.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index c955544b9a02f..fd4a2af95a55c 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -704,13 +704,13 @@ spec_tuple_impl!( ((T, t, ExtendT, 0), @, @), ((U, u, ExtendU, 1), SpecTupleExtend2, default_extend_tuple_2), ((V, v, ExtendV, 2), SpecTupleExtend3, default_extend_tuple_3), - ((X, x, ExtendX, 3), SpecTupleExtend4, default_extend_tuple_4), - ((Y, y, ExtendY, 4), SpecTupleExtend5, default_extend_tuple_5), - ((Z, z, ExtendZ, 5), SpecTupleExtend6, default_extend_tuple_6), - ((A, a, ExtendA, 6), SpecTupleExtend7, default_extend_tuple_7), - ((B, b, ExtendB, 7), SpecTupleExtend8, default_extend_tuple_8), - ((C, c, ExtendC, 8), SpecTupleExtend9, default_extend_tuple_9), - ((D, d, ExtendD, 9), SpecTupleExtend10, default_extend_tuple_10), - ((E, e, ExtendE, 10), SpecTupleExtend11, default_extend_tuple_11), - ((F, f, ExtendF, 11), SpecTupleExtend12, default_extend_tuple_12), + ((W, w, ExtendW, 3), SpecTupleExtend4, default_extend_tuple_4), + ((X, x, ExtendX, 4), SpecTupleExtend5, default_extend_tuple_5), + ((Y, y, ExtendY, 5), SpecTupleExtend6, default_extend_tuple_6), + ((Z, z, ExtendZ, 6), SpecTupleExtend7, default_extend_tuple_7), + ((A, a, ExtendA, 7), SpecTupleExtend8, default_extend_tuple_8), + ((B, b, ExtendB, 8), SpecTupleExtend9, default_extend_tuple_9), + ((C, c, ExtendC, 9), SpecTupleExtend10, default_extend_tuple_10), + ((D, d, ExtendD, 10), SpecTupleExtend11, default_extend_tuple_11), + ((E, e, ExtendE, 11), SpecTupleExtend12, default_extend_tuple_12), ); From 9341954585b7b9bcfbbf1dbc406113ffe5154a0d Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Sat, 22 Feb 2025 01:09:51 +0100 Subject: [PATCH 9/9] Add tests for `Extend<(T, U)> for (ExtendT, ExtendU)` ordering of side-effects to `coretest`. --- .../coretests/tests/iter/traits/iterator.rs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/library/coretests/tests/iter/traits/iterator.rs b/library/coretests/tests/iter/traits/iterator.rs index e31d2e15b6d7e..5ef1f797ae55d 100644 --- a/library/coretests/tests/iter/traits/iterator.rs +++ b/library/coretests/tests/iter/traits/iterator.rs @@ -1,3 +1,5 @@ +use core::cell::RefCell; +use core::iter::zip; use core::num::NonZero; /// A wrapper struct that implements `Eq` and `Ord` based on the wrapped @@ -642,6 +644,26 @@ fn test_collect_for_tuples() { assert!(e.2 == d); } +#[test] +fn test_extend_for_tuple_side_effects_order() { + struct TrackingExtender<'a, T>(&'static str, &'a RefCell)>>, Vec); + impl Extend for TrackingExtender<'_, T> { + fn extend>(&mut self, i: I) { + let items = Vec::from_iter(i); + self.1.borrow_mut().push((self.0, items.clone())); + self.2.extend(items); + } + } + + let effects = RefCell::new(vec![]); + let l = TrackingExtender("l", &effects, vec![]); + let r = TrackingExtender("r", &effects, vec![]); + let mut p = ((l, r), ()); + p.extend(zip([(1, 2), (3, 4)], [(), ()])); + let effects = effects.into_inner(); + assert_eq!(effects, [("l", vec![1]), ("r", vec![2]), ("l", vec![3]), ("r", vec![4])]); +} + // just tests by whether or not this compiles fn _empty_impl_all_auto_traits() { use std::panic::{RefUnwindSafe, UnwindSafe};