Description
Updated test (play):
use std::marker::PhantomData;
struct Foo<T> {
marker: PhantomData<T>
}
trait Bar {}
impl<T: Bar> Clone for Foo<T> {
fn clone(&self) -> Foo<T> { Foo {marker: PhantomData} }
}
#[derive(Clone)]
struct Baz<T> {
x: Foo<T>
}
fn main() {}
(I'll try to update the above as necessary.)
The error message is pretty good now, actually; the only thing I'd want beyond this is for the diagnostic to point out that Baz
is trying to automatically derive Clone
(which is why it is missing the necessary T: Bar
bound), and that a manual implementation with that bound would work.
Original bug report follows.
use std::hashmap::HashSet;
#[deriving(Clone)]
struct FollowSet<T> {
right: HashSet<T>,
can_end: bool,
}
Error message from rustc:
% rustc --lib /tmp/f.rs
/tmp/f.rs:3:11: 3:16 error: failed to find an implementation of trait std::to_bytes::IterBytes for T
/tmp/f.rs:3 #[deriving(Clone)]
^~~~~
I saw the above, and said "why does it matter about whether I implement IterBytes
when I want to implement Clone
here. (Then I read source code for hashmap.rs
and saw that we actually build up the new table from scratch, rather than copying the existing underlying representation directly; so that explains why one needs it.)
Anyway, it would be good if the error message actually pointed us at the use of HashSet<T>
in the definition of struct FollowSet
above.
Oh, also: Is there actually a way for one to use deriving here for this? As far as I can tell, I'm going to be forced to manually implement Clone
. (Its not hard to do, just a little surprising.)
(not a true dupe of #7621 since that discussing errors when deriving Clone and constituents do not implement Clone. Here, we determine that the constituent does implement Clone, if some it implements some other trait as well. But its possible that a solution for one would also resolve the other.)