3 ms·
By creating `f` you're in essence trying to borrow something that's mutably borrowed already, which the borrow checker doesn't allow. I guess I could see some l
by Klonoar 4y ago
By creating `f` you're in essence trying to borrow something that's mutably borrowed already, which the borrow checker doesn't allow. I guess I could see some logic for this being possible, but in practice I've never encountered this in any Rust codebase I've gone through.
The trivial example fix is just to... ensure it can copy, and tweak the match line:
#[derive(Copy, Clone, Debug)]
struct Foo {
a: i32
}
fn thing(foo: &mut Foo) {
match *foo {
f @ Foo { a } if a > 5 => {
println!("{:?}", f)
}
_ => {}
}
}
fn main() {
let mut x = Foo { a: 1 };
thing(&mut x);
}
If the struct was bigger and/or had types that couldn't copy, I'd refrain from trying to shoehorn matching like that entirely.
- Measter 4y agoThe borrow checker does allow that, though, as long the uses don't interleave and the references created correctly. As long as `f` is not used between `a`'s creation and last use, and `a` comes from `f`, it's valid for that alias to exist. You can see that with this code example, which is accepted: #[derive(Debug)] pub struct Foo { a: i32 } impl Foo { fn get_a(&mut self) -> &mut i32 { &mut self.a } } pub fn thing(mut foo: &mut Foo) { let f = &mut foo; let a = f.get_a(); if *a > 5 { println!("{:?}", f); } } That's why I was so surprised the compiler rejected it.