If I get correctly it is not possible to create a mutable borrow over a std::rc::Rc
in Rust, you have to use Cell
or RefCell
.
But anyway I cannot understand how to use them. For example consider this simple example:
use std::cell::RefCell;
struct X (i32);
impl X {
fn foo(&mut self) {
self.0 = 0;
}
}
fn main () {
let x = X(5);
let rcx = RefCell::new(&x);
let mut mutx: std::cell::RefMut<&X> = rcx.borrow_mut();
(*mutx).foo();
}
I get the following error:
16:5: 16:9 error: cannot borrow immutable local variable `mutx` as mutable
16 mutx.foo();
But if I remove the reference from line (and update type of mutx
):
let rcx = RefCell::new(x);
Everything is fine. But I cannot understand why, since RefMut::deref_mut() -> &mut T
the deference called at line 16 should return &&mut T
in the first case, while &mut T
in the second case. But since the compiler should apply many *
as needed (If I get how deref coercion works) there should be no difference between RefMut<X>::deref_mut()
and RefMut<&X>::deref_mut()
Edit:
By mistake I forgot to write mut
at line 15 as in the linked example is correctly is written. So now it's let mut mutx...
The problem stems from the fact that you've stored an immutable reference in the RefCell
. I'm unclear why you would want such a thing. The normal pattern is to put the entire value into the RefCell
, not just a reference:
fn main () {
let rcx = RefCell::new(X(5));
let mut mutx = rcx.borrow_mut();
mutx.foo();
}
Problem from original question
You have two compounding errors. Let's check the entire error message:
<anon>:16:5: 16:12 error: cannot borrow immutable borrowed content as mutable
<anon>:16 (*mutx).foo();
^~~~~~~
<anon>:16:7: 16:11 error: cannot borrow immutable local variable `mutx` as mutable
<anon>:16 (*mutx).foo();
^~~~
Note the second error — "cannot borrow immutable local variable mutx
". That's because you need to declare the mutx
variable mutable:
let mut mutx: std::cell::RefMut<&X> = rcx.borrow_mut();
That will allow mutx
to participate in DerefMut
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With