Reputation: 2352
The following code:
use std::borrow::Cow;
struct Hip<'a> {
hip: Cow<'a, [u8]>
}
struct Hop<'a, T: ?Sized + 'a> {
hop: Cow<'a, T>
}
fn main() {
let it_be: Hop<[u8]> = [1, 2, 3];
}
Fails to build because "the trait Clone
is not implemented for T
".
Whereas expecting T
to implement Clone
(as follows):
struct Hop<'a, T: Clone + ?Sized + 'a> {
hop: Cow<'a, T>
}
Fails to build because "the trait Clone
is not implemented for [u8]
".
How come Hip
, which is using a [u8]
, compiles, but not Hop
?
Why does the compiler request Clone
to be implemented for Hop
's T
, but not for Hip
's [u8]
?
Upvotes: 2
Views: 245
Reputation: 2352
The documentation says the type should implement ToOwned
.
The following works:
struct Hop<'a, T: ?Sized + ToOwned> {
hop: Cow<'a, T>
}
fn main() {
let it_be: Hop<[u8]> = Hop { hop: Cow::Owned(vec![1, 2, 3]) };
}
About the error message: the compiler generates the implementation of ToOwned
for every type implementing Clone
. So when the trait ToOwned
is missing, it suggests to implement Clone
.
This is a mistake because some types have good reasons to implement ToOwned
without implementing Clone
. [u8]
is one of them, hence Hip
compiles. Whereas Hop
's T
was not bound to ToOwned
, so it fails.
Upvotes: 3