about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-04-17 03:05:13 +0200
committerGitHub <noreply@github.com>2020-04-17 03:05:13 +0200
commitd19458784f3f25e53484f58f66aef8b973f002bc (patch)
treecadc8be922554d6ba256c05534c979eb74006f43
parentabd72f7fc2ced909ef21b9eb8029a392c4211c66 (diff)
parentabe5973b9d1202f1a6460c0116f22fc33c9506c5 (diff)
downloadrust-d19458784f3f25e53484f58f66aef8b973f002bc.tar.gz
rust-d19458784f3f25e53484f58f66aef8b973f002bc.zip
Rollup merge of #70910 - rakshith-ravi:master, r=cuviper
Hides default fns inside Fuse impl to avoid exposing it to any crate

Fixes #70796

@cuviper I've added some default, private traits to do the job for us. If required, I can expose them to a specific visibility if you want to call these functions for #70332

r? @cuviper
-rw-r--r--src/libcore/iter/adapters/fuse.rs307
1 files changed, 244 insertions, 63 deletions
diff --git a/src/libcore/iter/adapters/fuse.rs b/src/libcore/iter/adapters/fuse.rs
index 23bc215aa77..502fc2e6315 100644
--- a/src/libcore/iter/adapters/fuse.rs
+++ b/src/libcore/iter/adapters/fuse.rs
@@ -44,6 +44,19 @@ macro_rules! fuse {
     };
 }
 
+// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
+// Implementing this as a directly-expanded macro helps codegen performance.
+macro_rules! unchecked {
+    ($self:ident) => {
+        match $self {
+            Fuse { iter: Some(iter) } => iter,
+            // SAFETY: the specialized iterator never sets `None`
+            Fuse { iter: None } => unsafe { intrinsics::unreachable() },
+        }
+    };
+}
+
+// Any implementation here is made internal to avoid exposing default fns outside this trait
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I> Iterator for Fuse<I>
 where
@@ -52,6 +65,193 @@ where
     type Item = <I as Iterator>::Item;
 
     #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        FuseImpl::next(self)
+    }
+
+    #[inline]
+    fn nth(&mut self, n: usize) -> Option<I::Item> {
+        FuseImpl::nth(self, n)
+    }
+
+    #[inline]
+    fn last(self) -> Option<Self::Item> {
+        FuseImpl::last(self)
+    }
+
+    #[inline]
+    fn count(self) -> usize {
+        FuseImpl::count(self)
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        FuseImpl::size_hint(self)
+    }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
+    where
+        Self: Sized,
+        Fold: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+    {
+        FuseImpl::try_fold(self, acc, fold)
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        FuseImpl::fold(self, acc, fold)
+    }
+
+    #[inline]
+    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+    where
+        P: FnMut(&Self::Item) -> bool,
+    {
+        FuseImpl::find(self, predicate)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> DoubleEndedIterator for Fuse<I>
+where
+    I: DoubleEndedIterator,
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
+        FuseImpl::next_back(self)
+    }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
+        FuseImpl::nth_back(self, n)
+    }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
+    where
+        Self: Sized,
+        Fold: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+    {
+        FuseImpl::try_rfold(self, acc, fold)
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        FuseImpl::rfold(self, acc, fold)
+    }
+
+    #[inline]
+    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+    where
+        P: FnMut(&Self::Item) -> bool,
+    {
+        FuseImpl::rfind(self, predicate)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<I> ExactSizeIterator for Fuse<I>
+where
+    I: ExactSizeIterator,
+{
+    fn len(&self) -> usize {
+        FuseImpl::len(self)
+    }
+
+    fn is_empty(&self) -> bool {
+        FuseImpl::is_empty(self)
+    }
+}
+
+unsafe impl<I> TrustedRandomAccess for Fuse<I>
+where
+    I: TrustedRandomAccess,
+{
+    unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
+        match self.iter {
+            Some(ref mut iter) => iter.get_unchecked(i),
+            // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
+            None => intrinsics::unreachable(),
+        }
+    }
+
+    fn may_have_side_effect() -> bool {
+        I::may_have_side_effect()
+    }
+}
+
+// Fuse specialization trait
+#[doc(hidden)]
+trait FuseImpl<I> {
+    type Item;
+
+    // Functions specific to any normal Iterators
+    fn next(&mut self) -> Option<Self::Item>;
+    fn nth(&mut self, n: usize) -> Option<Self::Item>;
+    fn last(self) -> Option<Self::Item>;
+    fn count(self) -> usize;
+    fn size_hint(&self) -> (usize, Option<usize>);
+    fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
+    where
+        Self: Sized,
+        Fold: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>;
+    fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, Self::Item) -> Acc;
+    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+    where
+        P: FnMut(&Self::Item) -> bool;
+
+    // Functions specific to DoubleEndedIterators
+    fn next_back(&mut self) -> Option<Self::Item>
+    where
+        I: DoubleEndedIterator;
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item>
+    where
+        I: DoubleEndedIterator;
+    fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
+    where
+        Self: Sized,
+        Fold: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+        I: DoubleEndedIterator;
+    fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, Self::Item) -> Acc,
+        I: DoubleEndedIterator;
+    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+    where
+        P: FnMut(&Self::Item) -> bool,
+        I: DoubleEndedIterator;
+
+    // Functions specific to ExactSizeIterator
+    fn len(&self) -> usize
+    where
+        I: ExactSizeIterator;
+    fn is_empty(&self) -> bool
+    where
+        I: ExactSizeIterator;
+}
+
+// General Fuse impl
+#[doc(hidden)]
+impl<I> FuseImpl<I> for Fuse<I>
+where
+    I: Iterator,
+{
+    type Item = <I as Iterator>::Item;
+
+    #[inline]
     default fn next(&mut self) -> Option<<I as Iterator>::Item> {
         fuse!(self.iter.next())
     }
@@ -117,20 +317,20 @@ where
     {
         fuse!(self.iter.find(predicate))
     }
-}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> DoubleEndedIterator for Fuse<I>
-where
-    I: DoubleEndedIterator,
-{
     #[inline]
-    default fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
+    default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
+    where
+        I: DoubleEndedIterator,
+    {
         fuse!(self.iter.next_back())
     }
 
     #[inline]
-    default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
+    default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
+    where
+        I: DoubleEndedIterator,
+    {
         fuse!(self.iter.nth_back(n))
     }
 
@@ -140,6 +340,7 @@ where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Ok = Acc>,
+        I: DoubleEndedIterator,
     {
         if let Some(ref mut iter) = self.iter {
             acc = iter.try_rfold(acc, fold)?;
@@ -152,6 +353,7 @@ where
     default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
+        I: DoubleEndedIterator,
     {
         if let Some(iter) = self.iter {
             acc = iter.rfold(acc, fold);
@@ -163,24 +365,27 @@ where
     default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool,
+        I: DoubleEndedIterator,
     {
         fuse!(self.iter.rfind(predicate))
     }
-}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ExactSizeIterator for Fuse<I>
-where
-    I: ExactSizeIterator,
-{
-    default fn len(&self) -> usize {
+    #[inline]
+    default fn len(&self) -> usize
+    where
+        I: ExactSizeIterator,
+    {
         match self.iter {
             Some(ref iter) => iter.len(),
             None => 0,
         }
     }
 
-    default fn is_empty(&self) -> bool {
+    #[inline]
+    default fn is_empty(&self) -> bool
+    where
+        I: ExactSizeIterator,
+    {
         match self.iter {
             Some(ref iter) => iter.is_empty(),
             None => true,
@@ -188,20 +393,8 @@ where
     }
 }
 
-// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
-// Implementing this as a directly-expanded macro helps codegen performance.
-macro_rules! unchecked {
-    ($self:ident) => {
-        match $self {
-            Fuse { iter: Some(iter) } => iter,
-            // SAFETY: the specialized iterator never sets `None`
-            Fuse { iter: None } => unsafe { intrinsics::unreachable() },
-        }
-    };
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I> Iterator for Fuse<I>
+#[doc(hidden)]
+impl<I> FuseImpl<I> for Fuse<I>
 where
     I: FusedIterator,
 {
@@ -255,20 +448,20 @@ where
     {
         unchecked!(self).find(predicate)
     }
-}
 
-#[stable(feature = "fused", since = "1.26.0")]
-impl<I> DoubleEndedIterator for Fuse<I>
-where
-    I: DoubleEndedIterator + FusedIterator,
-{
     #[inline]
-    fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
+    fn next_back(&mut self) -> Option<<I as Iterator>::Item>
+    where
+        I: DoubleEndedIterator,
+    {
         unchecked!(self).next_back()
     }
 
     #[inline]
-    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
+    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
+    where
+        I: DoubleEndedIterator,
+    {
         unchecked!(self).nth_back(n)
     }
 
@@ -278,6 +471,7 @@ where
         Self: Sized,
         Fold: FnMut(Acc, Self::Item) -> R,
         R: Try<Ok = Acc>,
+        I: DoubleEndedIterator,
     {
         unchecked!(self).try_rfold(init, fold)
     }
@@ -286,6 +480,7 @@ where
     fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
     where
         Fold: FnMut(Acc, Self::Item) -> Acc,
+        I: DoubleEndedIterator,
     {
         unchecked!(self).rfold(init, fold)
     }
@@ -294,38 +489,24 @@ where
     fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
     where
         P: FnMut(&Self::Item) -> bool,
+        I: DoubleEndedIterator,
     {
         unchecked!(self).rfind(predicate)
     }
-}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<I> ExactSizeIterator for Fuse<I>
-where
-    I: ExactSizeIterator + FusedIterator,
-{
-    fn len(&self) -> usize {
+    #[inline]
+    fn len(&self) -> usize
+    where
+        I: ExactSizeIterator,
+    {
         unchecked!(self).len()
     }
 
-    fn is_empty(&self) -> bool {
+    #[inline]
+    fn is_empty(&self) -> bool
+    where
+        I: ExactSizeIterator,
+    {
         unchecked!(self).is_empty()
     }
 }
-
-unsafe impl<I> TrustedRandomAccess for Fuse<I>
-where
-    I: TrustedRandomAccess,
-{
-    unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
-        match self.iter {
-            Some(ref mut iter) => iter.get_unchecked(i),
-            // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
-            None => intrinsics::unreachable(),
-        }
-    }
-
-    fn may_have_side_effect() -> bool {
-        I::may_have_side_effect()
-    }
-}