It's well known that the following:
#[derive(Clone)]
struct Foo<T>(PhantomData<T>);
Yields:
impl<T: Clone> Clone for Foo<T> { /* */ }
Instead of
impl<T> Clone for Foo<T> where PhantomData<T>: Clone { /* */ }
And the reasons for why have been discussed here on IRLO.
What I'm thinking the language is lacking is an extra diagnostic, hence this post to gauge interest and feedback before I open an issue. Suppose I want to do:
fn bar<T: Clone>(_: T) {}
#[derive(Default)]
struct DefaultNotClone;
// assume I've also done a #[derive(Default)] for Foo
bar(Foo::<DefaultNotClone>::default());
Currently I get:
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `Foo<DefaultNotClone>: Clone` is not satisfied
--> src/main.rs:10:9
|
10 | bar(Foo::<DefaultNotClone>::default());
| --- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Foo<DefaultNotClone>`
| |
| required by a bound introduced by this call
|
note: required for `Foo<DefaultNotClone>` to implement `Clone`
--> src/main.rs:1:19
|
1 | #[derive(Default, Clone)]
| ^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `bar`
--> src/main.rs:7:11
|
7 | fn bar<T: Clone>(_: T) {}
| ^^^^^ required by this bound in `bar`
help: consider borrowing here
|
10 | bar(&Foo::<DefaultNotClone>::default());
| +
But I think it would be useful if the compiler, when possible (i.e. when it can easily tell that the field does implement Clone, and omitted for the cases involving extra analysis) could warn the user that they might've assumed a perfect derive (i.e. the one with a where clause) instead of actual derive behaviour:
help: derive produces bounds on generics rather than fields
|
10 | bar(Foo::<DefaultNotClone>::default());
| ^^^^^^^^^^^^^^^ derive expects this to implement `Clone`
...
|
2 | struct Foo<T>(std::marker::PhantomData<T>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ despite this implementing `Clone`
Not super happy with the exact wording, but something along those lines would be useful to let users who are new to this particular part of the derive rules know why they're encountering this issue.
P.S. didn't know which category this would best fit in, but since I'm asking about a helpful diagnostic emitted by the compiler, it seemed appropriate to put it in the compiler category.