about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-10-23 05:28:26 +0200
committerGitHub <noreply@github.com>2021-10-23 05:28:26 +0200
commit270c800d358ee47f3aee6fe1e2ec4dc92616d55f (patch)
tree44be21de57be83c7ee4d198f16c9b940dc04c223
parentc400feeb84f6164edd2d78607218ac8a58754cc3 (diff)
parentafcee19d88658e54f4a3c82892ba6d937e0f78d4 (diff)
downloadrust-270c800d358ee47f3aee6fe1e2ec4dc92616d55f.tar.gz
rust-270c800d358ee47f3aee6fe1e2ec4dc92616d55f.zip
Rollup merge of #90117 - calebsander:fix/rsplit-clone, r=yaahc
Make RSplit<T, P>: Clone not require T: Clone

This addresses a TODO comment. The behavior of `#[derive(Clone)]` *does* result in a `T: Clone` requirement. Playground example:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a8b1a9581ff8893baf401d624a53d35b

Add a manual `Clone` implementation, mirroring `Split` and `SplitInclusive`.
`(R)?SplitN(Mut)?` don't have any `Clone` implementations, but I'll leave that for its own pull request.
-rw-r--r--library/core/src/slice/iter.rs12
-rw-r--r--src/test/ui/iterators/rsplit-clone.rs11
2 files changed, 22 insertions, 1 deletions
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index dbf97851b03..07ecae78303 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -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 @@ where
     }
 }
 
+// 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
index 00000000000..911da742957
--- /dev/null
+++ b/src/test/ui/iterators/rsplit-clone.rs
@@ -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();
+}