]> git.lizzy.rs Git - rust.git/commitdiff
Make RSplit<T, P>: Clone not require T: Clone
authorCaleb Sander <caleb.sander@gmail.com>
Thu, 21 Oct 2021 00:04:01 +0000 (17:04 -0700)
committerCaleb Sander <caleb.sander@gmail.com>
Fri, 22 Oct 2021 04:25:59 +0000 (21:25 -0700)
This addresses a TODO comment. The behavior of #[derive(Clone)]
*does* result in a T: Clone requirement.

Add a manual Clone implementation, matching Split and SplitInclusive.

library/core/src/slice/iter.rs
src/test/ui/iterators/rsplit-clone.rs [new file with mode: 0644]

index dbf97851b03e4e78294871ae94ba0d92f9836529..07ecae7830351eac72860ea614923af9ab9d8ec1 100644 (file)
@@ -839,7 +839,6 @@ impl<T, P> FusedIterator for SplitInclusiveMut<'_, T, P> where P: FnMut(&T) -> b
 /// [`rsplit`]: slice::rsplit
 /// [slices]: slice
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
-#[derive(Clone)] // Is this correct, or does it incorrectly require `T: Clone`?
 pub struct RSplit<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
@@ -867,6 +866,17 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "slice_rsplit", since = "1.27.0")]
+impl<T, P> Clone for RSplit<'_, T, P>
+where
+    P: Clone + FnMut(&T) -> bool,
+{
+    fn clone(&self) -> Self {
+        RSplit { inner: self.inner.clone() }
+    }
+}
+
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
 impl<'a, T, P> Iterator for RSplit<'a, T, P>
 where
diff --git a/src/test/ui/iterators/rsplit-clone.rs b/src/test/ui/iterators/rsplit-clone.rs
new file mode 100644 (file)
index 0000000..911da74
--- /dev/null
@@ -0,0 +1,11 @@
+// check-pass
+
+// RSplit<T, P> previously required T: Clone in order to be Clone
+
+struct NotClone;
+
+fn main() {
+    let elements = [NotClone, NotClone, NotClone];
+    let rsplit = elements.rsplit(|_| false);
+    rsplit.clone();
+}