When I manually implement Clone
and Copy
they work:
use std::fmt::Debug;
// #[derive(Debug, Clone, Copy)]
#[derive(Debug)]
struct Refs<'a, A, B> where &'a A: Copy, &'a B: Copy {
a: &'a A,
b: &'a B,
}
impl<'a, A, B> Clone for Refs<'a, A, B> {
fn clone(&self) -> Self {
Self {
a: self.a,
b: self.b,
}
}
}
impl<'a, A, B> Copy for Refs<'a, A, B> {}
trait Take {
fn take(self);
}
impl<'a, A: Debug, B: Debug> Take for Refs<'a, A, B> {
fn take(self) {
println!("took {self:?}");
}
}
#[derive(Debug)]
struct Hi {
a: f32,
}
#[derive(Debug)]
struct Bye {
a: f32,
}
fn main() {
let a = Hi { a: 1.0 };
let b = Bye { a: 2.0 };
let refs = Refs { a: &a, b: &b };
refs.take();
refs.take();
}
Output:
took Refs { a: Hi { a: 1.0 }, b: Bye { a: 2.0 } }
took Refs { a: Hi { a: 1.0 }, b: Bye { a: 2.0 } }
When I try to #[derive]
them I get errors:
use std::fmt::Debug;
#[derive(Debug, Clone, Copy)]
// #[derive(Debug)]
struct Refs<'a, A, B> where &'a A: Copy, &'a B: Copy {
a: &'a A,
b: &'a B,
}
/*
impl<'a, A, B> Clone for Refs<'a, A, B> {
fn clone(&self) -> Self {
Self {
a: self.a,
b: self.b,
}
}
}
impl<'a, A, B> Copy for Refs<'a, A, B> {}
*/
trait Take {
fn take(self);
}
impl<'a, A: Debug, B: Debug> Take for Refs<'a, A, B> {
fn take(self) {
println!("took {self:?}");
}
}
#[derive(Debug)]
struct Hi {
a: f32,
}
#[derive(Debug)]
struct Bye {
a: f32,
}
fn main() {
let a = Hi { a: 1.0 };
let b = Bye { a: 2.0 };
let refs = Refs { a: &a, b: &b };
refs.take();
refs.take();
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0382]: use of moved value: `refs`
--> src/main.rs:48:5
|
46 | let refs = Refs { a: &a, b: &b };
| ---- move occurs because `refs` has type `Refs<'_, Hi, Bye>`, which does not implement the `Copy` trait
47 | refs.take();
| ------ `refs` moved due to this method call
48 | refs.take();
| ^^^^ value used here after move
|
note: `Take::take` takes ownership of the receiver `self`, which moves `refs`
--> src/main.rs:24:13
|
24 | fn take(self);
| ^^^^
help: you could `clone` the value and consume it, if the following trait bounds could be satisfied: `Hi: Clone` and `Bye: Clone`
|
47 | refs.clone().take();
| ++++++++
help: consider annotating `Hi` with `#[derive(Clone)]`
|
34 + #[derive(Clone)]
35 | struct Hi {
|
help: consider annotating `Bye` with `#[derive(Clone)]`
|
39 + #[derive(Clone)]
40 | struct Bye {
|
For more information about this error, try `rustc --explain E0382`.
error: could not compile `playground` (bin "playground") due to 1 previous error
My question is why? Could this be a bug? Is there a reason why Copy
derive is limited?