rustborrow-checkerrefcell

Rust Rc<RefCell>::borrow_mut returns &mut Rc<RefCell<T>> instead of RefMut<T>


so I'm relatively new in Rust and I was trying to get something similair to a std::shared_ptr in C++. I decided to go with the Rc<RefCell> pattern.

I'm trying to get and modify the value of Rc<RefCell<i32>> but borrow_mut() keeps returning &mut Rc<RefCell<i32>> instead of MutRef<i32>

I'm working on 2 projects currently. In the first project test_mut is of type RefMut<i32>.

let mut test: Rc<RefCell<i32>> = Rc::new(RefCell::new(5));
let test_mut = test.borrow_mut();

But in my other project test_mut is of type &mut Rc<RefCell<i32>>.

WHYYY??

When I don't let the compiler deduct the type and replace the code with:

let mut test: Rc<RefCell<i32>> = Rc::new(RefCell::new(5));
let test_mut: RefMut<i32> = test.borrow_mut();

I get the following error:

mismatched types
expected struct `RefMut<'_, i32>`
found mutable reference `&mut Rc<RefCell<i32>>`

If anyone has any idea how I can prevent this, you would be my hero :)


Solution

  • Locke's comment is right.

    Because of the method resolution rules, if you have use std::borrow::BorrowMut;, BorrowMut::borrow_mut will get called instead of RefCell::borrow_mut. Basically, trait methods on the current type (&mut RefCell) are checked before methods on the deref type (&Rc).

    You can either remove the import, or call it as an associated function:

    let test_mut = RefCell::borrow_mut(&test);
    

    This isn't necessary here, but the equivalent code without automatic deref would be:

    use std::ops::Deref;
    let test_mut = RefCell::borrow_mut(Deref::deref(&test))