Consider the following source:
use std::cell::RefCell;
use std::ops::DerefMut;
struct Point(usize, usize);
fn main() {
let origin = RefCell::new(Point(400, 300));
let mut br = origin.borrow_mut();
let org = br.deref_mut();
// let org = &mut br;
let xmut = &mut org.0;
let ymut = &mut org.1;
*xmut = 800;
*ymut = 600;
}
Here, origin
is a Point
struct wrapped into RefCell
and is borrowed later as br
with type RefMut
. Then, borrow_mut
from trait DerefMut
is called and get org: &Point
. Finally, each member can be mutably borrowed, simultaneously. (By the way, is this analysis correct?)
I noticed I can use dot syntax to access br: RefMut
to get the corresponding member of the wrapped Point
struct. For example, for accessing one single member:
let org = &mut br;
let xmut = &mut org.0; // notice: only xmut and no ymut here
*xmut = 800;
However, rustc compiles org
is wrongly borrowed when the two member are mutably borrowed at the same time.
use std::cell::RefCell;
use std::ops::DerefMut;
struct Point(usize, usize);
fn main() {
let origin = RefCell::new(Point(400, 300));
let mut br = origin.borrow_mut();
let org = &mut br; // here
let xmut = &mut org.0; // now here are both xmut and ymut.
let ymut = &mut org.1;
*xmut = 800;
*ymut = 600;
}
error[E0499]: cannot borrow `*org` as mutable more than once at a time
--> src/main.rs:13:21
So two confusing questions have emerged:
First, why is dot syntax applicable to br: RefMut
to access the members of Point
struct? Is there an implicit trait method call?
Second, why does the &mut br
crash but the explicit deref_mut()
work? What's the difference between the two ways in sight of rustc? Besides, how to fix the program in &mut br
way?
Thanks.