Hello,
I'm stumbling over a seemingly very simply borrowchecker issue:
#![allow(unused_variables)]
pub struct A;
pub struct B;
pub struct AConf;
pub struct BConf;
impl A {
pub fn new(conf: AConf) -> Self { A }
pub fn update_conf(&mut self, conf: AConf) {}
}
impl B {
pub fn new(conf: BConf) -> Self { B }
pub fn update_conf(&mut self, conf: BConf) {}
}
enum MyType {
A(A),
B(B),
}
enum MyTypeConf {
A(AConf),
B(BConf),
}
impl MyType {
fn update_conf(&mut self, conf: MyTypeConf) {
match (self, conf) {
(MyType::A(a), MyTypeConf::A(a_conf)) => a.update_conf(a_conf),
(MyType::B(b), MyTypeConf::B(b_conf)) => b.update_conf(b_conf),
(MyType::A(_), MyTypeConf::B(b_conf)) => *self = MyType::B(B::new(b_conf)),
(MyType::B(_), MyTypeConf::A(a_conf)) => *self = MyType::A(A::new(a_conf))
}
}
}
This fails to compile, because match (self, conf)
moves self
, so I cannot dereference it later. The problem is if I try to match on &self
, I cannot take a mutable reference to the content of MyType
, in the first two branches of the match... Is there a clever way to make the borrow checker understand my intent here?
Link to the playgorund: Rust Playground
And the error:
error[E0382]: use of moved value: `self`
--> src/lib.rs:33:54
|
29 | fn update_conf(&mut self, conf: MyTypeConf) {
| --------- move occurs because `self` has type `&mut MyType`, which does not implement the `Copy` trait
30 | match (self, conf) {
| ---- value moved here
...
33 | (MyType::A(_), MyTypeConf::B(b_conf)) => *self = MyType::B(B::new(b_conf)),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value used here after move