Hello. I found something a little suboptimal when trying to split a borrow in a struct referenced by a a RefMut (from a RefCell). The borrow checker seems a little bit overeager.
Here's a simplified version of the code.
use std::cell::{RefCell};
pub struct SubStructA {
a : usize
}
pub struct SubStructB {
b : usize
}
impl SubStructB {
pub fn do_something_with_a(&mut self, a : &SubStructA) {
println!("{}, {}", a.a, self.b);
}
}
pub struct TopStruct {
a : SubStructA,
b : SubStructB
}
fn main() {
//--SPLIT BORROW WORKS GREAT----------------------------------------------
let mut top_struct = TopStruct{a : SubStructA{a : 1}, b : SubStructB{b : 2}};
let my_top_ref = &mut top_struct;
my_top_ref.b.do_something_with_a(&my_top_ref.a);
//--FAILS TO COMPILE----------------------------------------------
let top_ref_cell : RefCell<TopStruct> = RefCell::new(TopStruct{a : SubStructA{a : 1}, b : SubStructB{b : 2}});
let mut my_top_ref = top_ref_cell.borrow_mut();
my_top_ref.b.do_something_with_a(&my_top_ref.a);
}
And the borrow checker says this:
error[E0502]: cannot borrow `my_top_ref` as immutable because it is also borrowed as mutable
--> src/main.rs:34:39
|
34 | my_top_ref.b.do_something_with_a(&my_top_ref.a);
| ---------- ------------------- ^^^^^^^^^^ immutable borrow occurs here
| | |
| | mutable borrow later used by call
| mutable borrow occurs here
Anyway, there are several work-arounds I've found so it's not critical. It just struck me as a place where things weren't orthogonal, and I was wondering if anyone had any opinions about it. ie. whether I'm thinking about refs all wrong, or whether it's a rough edge in the language that could be smoothed out?
Thanks everyone.