Skip to content

Commit 5df05c6

Browse files
committed
specialize zip: Use associated type for specialized zip struct data
The associated type must be 'static to avoid dropck related errors.
1 parent 85cd49f commit 5df05c6

File tree

1 file changed

+39
-13
lines changed

1 file changed

+39
-13
lines changed

src/libcore/iter/mod.rs

+39-13
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@
301301

302302
use clone::Clone;
303303
use cmp;
304+
use default::Default;
304305
use fmt;
305306
use iter_private::TrustedRandomAccess;
306307
use ops::FnMut;
@@ -624,8 +625,7 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
624625
pub struct Zip<A, B> {
625626
a: A,
626627
b: B,
627-
index: usize,
628-
len: usize,
628+
spec: <(A, B) as ZipImplData>::Data,
629629
}
630630

631631
#[stable(feature = "rust1", since = "1.0.0")]
@@ -667,6 +667,17 @@ trait ZipImpl<A, B> {
667667
B: DoubleEndedIterator + ExactSizeIterator;
668668
}
669669

670+
// Zip specialization data members
671+
#[doc(hidden)]
672+
trait ZipImplData {
673+
type Data: 'static + Clone + Default + fmt::Debug;
674+
}
675+
676+
#[doc(hidden)]
677+
impl<T> ZipImplData for T {
678+
default type Data = ();
679+
}
680+
670681
// General Zip impl
671682
#[doc(hidden)]
672683
impl<A, B> ZipImpl<A, B> for Zip<A, B>
@@ -677,8 +688,7 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
677688
Zip {
678689
a: a,
679690
b: b,
680-
index: 0, // not used in general case
681-
len: 0,
691+
spec: Default::default(), // unused
682692
}
683693
}
684694

@@ -731,6 +741,20 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
731741
}
732742
}
733743

744+
#[doc(hidden)]
745+
#[derive(Default, Debug, Clone)]
746+
struct ZipImplFields {
747+
index: usize,
748+
len: usize,
749+
}
750+
751+
#[doc(hidden)]
752+
impl<A, B> ZipImplData for (A, B)
753+
where A: TrustedRandomAccess, B: TrustedRandomAccess
754+
{
755+
type Data = ZipImplFields;
756+
}
757+
734758
#[doc(hidden)]
735759
impl<A, B> ZipImpl<A, B> for Zip<A, B>
736760
where A: TrustedRandomAccess, B: TrustedRandomAccess
@@ -740,16 +764,18 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
740764
Zip {
741765
a: a,
742766
b: b,
743-
index: 0,
744-
len: len,
767+
spec: ZipImplFields {
768+
index: 0,
769+
len: len,
770+
}
745771
}
746772
}
747773

748774
#[inline]
749775
fn next(&mut self) -> Option<(A::Item, B::Item)> {
750-
if self.index < self.len {
751-
let i = self.index;
752-
self.index += 1;
776+
if self.spec.index < self.spec.len {
777+
let i = self.spec.index;
778+
self.spec.index += 1;
753779
unsafe {
754780
Some((self.a.get_unchecked(i), self.b.get_unchecked(i)))
755781
}
@@ -760,7 +786,7 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
760786

761787
#[inline]
762788
fn size_hint(&self) -> (usize, Option<usize>) {
763-
let len = self.len - self.index;
789+
let len = self.spec.len - self.spec.index;
764790
(len, Some(len))
765791
}
766792

@@ -769,9 +795,9 @@ impl<A, B> ZipImpl<A, B> for Zip<A, B>
769795
where A: DoubleEndedIterator + ExactSizeIterator,
770796
B: DoubleEndedIterator + ExactSizeIterator
771797
{
772-
if self.index < self.len {
773-
self.len -= 1;
774-
let i = self.len;
798+
if self.spec.index < self.spec.len {
799+
self.spec.len -= 1;
800+
let i = self.spec.len;
775801
unsafe {
776802
Some((self.a.get_unchecked(i), self.b.get_unchecked(i)))
777803
}

0 commit comments

Comments
 (0)