From c6566a8037f9b3597df741f0ce1b59289441bd23 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Mon, 24 Jul 2023 19:58:13 +0200 Subject: [PATCH] Explain more clearly why `fn() -> T` can't be `#[derive(Clone)]` --- library/core/src/clone.rs | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) 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(fn() -> T); +/// ``` +/// +/// the auto-derived implementations will have unnecessary `T: Copy` and `T: Clone` bounds: +/// +/// ``` +/// # struct Generate(fn() -> T); +/// +/// // Automatically derived +/// impl Copy for Generate { } +/// +/// // Automatically derived +/// impl Clone for Generate { +/// fn clone(&self) -> Generate { +/// 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(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],