]> git.lizzy.rs Git - rust.git/blobdiff - library/core/src/array/iter.rs
from review: add a comment why try_fold was chosen instead of fold
[rust.git] / library / core / src / array / iter.rs
index 61ab1b1faff89826be67617085c9a6e0def438ae..f6616399610a6a278ade82ae200044cb886ac4e1 100644 (file)
@@ -123,6 +123,27 @@ fn size_hint(&self) -> (usize, Option<usize>) {
         (len, Some(len))
     }
 
+    #[inline]
+    fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let data = &mut self.data;
+        // FIXME: This uses try_fold(&mut iter) instead of fold(iter) because the latter
+        //  would go through the blanket `impl Iterator for &mut I` implementation
+        //  which lacks inline annotations on its methods and adding those would be a larger
+        //  perturbation than using try_fold here.
+        //  Whether it would be beneficial to add those annotations should be investigated separately.
+        (&mut self.alive)
+            .try_fold::<_, _, Result<_, !>>(init, |acc, idx| {
+                // SAFETY: idx is obtained by folding over the `alive` range, which implies the
+                // value is currently considered alive but as the range is being consumed each value
+                // we read here will only be read once and then considered dead.
+                Ok(fold(acc, unsafe { data.get_unchecked(idx).assume_init_read() }))
+            })
+            .unwrap()
+    }
+
     fn count(self) -> usize {
         self.len()
     }