about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/clone.rs40
1 files changed, 40 insertions, 0 deletions
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index a6d6230d3a6..d7ca9c22dad 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -86,6 +86,46 @@
 /// }
 /// ```
 ///
+/// If we `derive`:
+///
+/// ```
+/// #[derive(Copy, Clone)]
+/// struct Generate<T>(fn() -> T);
+/// ```
+///
+/// the auto-derived implementations will have unnecessary `T: Copy` and `T: Clone` bounds:
+///
+/// ```
+/// # struct Generate<T>(fn() -> T);
+///
+/// // Automatically derived
+/// impl<T: Copy> Copy for Generate<T> { }
+///
+/// // Automatically derived
+/// impl<T: Clone> Clone for Generate<T> {
+///     fn clone(&self) -> Generate<T> {
+///         Generate(Clone::clone(&self.0))
+///     }
+/// }
+/// ```
+///
+/// The bounds are unnecessary because clearly the function itself should be
+/// copy- and cloneable even if its return type is not:
+///
+/// ```compile_fail,E0599
+/// #[derive(Copy, Clone)]
+/// struct Generate<T>(fn() -> T);
+///
+/// struct NotCloneable;
+///
+/// fn generate_not_cloneable() -> NotCloneable {
+///     NotCloneable
+/// }
+///
+/// Generate(generate_not_cloneable).clone(); // error: trait bounds were not satisfied
+/// // Note: With the manual implementations the above line will compile.
+/// ```
+///
 /// ## Additional implementors
 ///
 /// In addition to the [implementors listed below][impls],