I ran into a situation in which the Rust compiler rejects code I thought is valid. At the bottom of this message is a sample program demonstrating the compiler error. Compiler version is 1.42.0.
Summarizing the problem, I thought Rc<T>
always implements Clone
for any type T
—even if T
doesn't implement Clone
. Indeed, by itself in my program, Rc<B>
implements Clone
without the type B
implementing Clone
. However, when I contain Rc<B>
in my struct, the struct fails derive the Clone
trait, and I get a compiler error when I attempt to call the clone
method on it.
What's going on? What am I missing?
Also, I'm not looking for a workaround. I can explicitly implement Clone
rather than using the derived implementation to work around this problem. Instead, I'm looking to broaden my understanding of why this program is invalid.
Thanks!
use std::rc::Rc;
#[derive(Clone, Debug)]
struct A<T> {
inner: Rc<T>,
}
#[derive(Debug)]
struct B;
#[derive(Clone, Debug)]
struct C;
fn main() {
{
let a1 = Rc::new(B);
let a2 = a1.clone(); // OK
dbg!(a2);
}
{
let b = B;
let a1 = A { inner: Rc::new(b) };
let a2 = a1.clone(); // ERROR: error[E0599]: no method named `clone` found for struct `A<B>` in the current scope
dbg!(a2);
}
{
let c = C;
let a1 = A { inner: Rc::new(c) };
let a2 = a1.clone(); // OK
dbg!(a2);
}
}
Here is the compiler output.
$ rustc --version
rustc 1.42.0 (b8cedc004 2020-03-09)
$ cargo check
Checking rust v0.0.0 (/home/cbrandenburg/Art/scratch/rust)
error[E0599]: no method named `clone` found for struct `A<B>` in the current scope
--> src/main.rs:24:21
|
4 | struct A<T> {
| ----------- method `clone` not found for this
...
24 | let a2 = a1.clone(); // ERROR: error[E0599]: no method named `clone` found for struct `A<B>` in the current scope
| ^^^^^ method not found in `A<B>`
|
= note: the method `clone` exists but the following trait bounds were not satisfied:
`A<B> : std::clone::Clone`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `clone`, perhaps you need to implement it:
candidate #1: `std::clone::Clone`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0599`.
error: could not compile `rust`.
To learn more, run the command again with --verbose.