Skip to content

Commit ec0fb72

Browse files
authored
Rollup merge of rust-lang#114029 - Enselic:clone-doc, r=scottmcm
Explain more clearly why `fn() -> T` can't be `#[derive(Clone)]` Closes rust-lang#73480 The derived impls were generated with `rustc -Z unpretty=expanded main.rs` and the raw output is: ```rust struct Generate<T>(fn() -> T); #[automatically_derived] impl<T: ::core::marker::Copy> ::core::marker::Copy for Generate<T> { } #[automatically_derived] impl<T: ::core::clone::Clone> ::core::clone::Clone for Generate<T> { #[inline] fn clone(&self) -> Generate<T> { Generate(::core::clone::Clone::clone(&self.0)) } } ```
2 parents 67626b8 + c6566a8 commit ec0fb72

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

library/core/src/clone.rs

+40
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,46 @@
8686
/// }
8787
/// ```
8888
///
89+
/// If we `derive`:
90+
///
91+
/// ```
92+
/// #[derive(Copy, Clone)]
93+
/// struct Generate<T>(fn() -> T);
94+
/// ```
95+
///
96+
/// the auto-derived implementations will have unnecessary `T: Copy` and `T: Clone` bounds:
97+
///
98+
/// ```
99+
/// # struct Generate<T>(fn() -> T);
100+
///
101+
/// // Automatically derived
102+
/// impl<T: Copy> Copy for Generate<T> { }
103+
///
104+
/// // Automatically derived
105+
/// impl<T: Clone> Clone for Generate<T> {
106+
/// fn clone(&self) -> Generate<T> {
107+
/// Generate(Clone::clone(&self.0))
108+
/// }
109+
/// }
110+
/// ```
111+
///
112+
/// The bounds are unnecessary because clearly the function itself should be
113+
/// copy- and cloneable even if its return type is not:
114+
///
115+
/// ```compile_fail,E0599
116+
/// #[derive(Copy, Clone)]
117+
/// struct Generate<T>(fn() -> T);
118+
///
119+
/// struct NotCloneable;
120+
///
121+
/// fn generate_not_cloneable() -> NotCloneable {
122+
/// NotCloneable
123+
/// }
124+
///
125+
/// Generate(generate_not_cloneable).clone(); // error: trait bounds were not satisfied
126+
/// // Note: With the manual implementations the above line will compile.
127+
/// ```
128+
///
89129
/// ## Additional implementors
90130
///
91131
/// In addition to the [implementors listed below][impls],

0 commit comments

Comments
 (0)