Skip to content

Commit

Permalink
Explain more clearly why fn() -> T can't be #[derive(Clone)]
Browse files Browse the repository at this point in the history
  • Loading branch information
Enselic committed Jul 30, 2023
1 parent 092e4f4 commit c6566a8
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions library/core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down

0 comments on commit c6566a8

Please sign in to comment.