Morten Lohne
Morten Lohne

Reputation: 433

Passing the contents of a RefCell<&mut T> to a function

Calling methods on a borrowed RefCell<&mut T> (That is, a Ref<&mut T>) works as expected, but I can't seem to pass it to a function. Consider the following code:

use std::cell::RefCell;

fn main() {
    let mut nums = vec![1, 2, 3];
    foo(&mut nums);
    println!("{:?}", nums);
}

fn foo(nums: &mut Vec<usize>) {
    let num_cell = RefCell::new(nums);

    num_cell.borrow_mut().push(4);

    push_5(*num_cell.borrow_mut());
}

fn push_5(nums: &mut Vec<usize>) {
    nums.push(4);
}

num_cell.borrow_mut().push(4) works, but push_5(*num_cell.borrow_mut()) errors with:

error[E0389]: cannot borrow data mutably in a `&` reference
  --> src/main.rs:14:12
   |
14 |     push_5(*num_cell.borrow_mut());
   |            ^^^^^^^^^^^^^^^^^^^^^^ assignment into an immutable reference

After dereferencing the Ref, I expected to get the mutable reference inside so the error doesn't really make sense to me. What gives?

Upvotes: 4

Views: 2549

Answers (1)

the8472
the8472

Reputation: 43150

push_5(*num_cell.borrow_mut());

Remove the * and the compiler suggests

error[E0308]: mismatched types
  --> src/main.rs:14:12
   |
14 |     push_5(num_cell.borrow_mut());
   |            ^^^^^^^^^^^^^^^^^^^^^
   |            |
   |            expected mutable reference, found struct `std::cell::RefMut`
   |            help: consider mutably borrowing here: `&mut num_cell.borrow_mut()`
   |
   = note: expected type `&mut std::vec::Vec<usize>`
              found type `std::cell::RefMut<'_, &mut std::vec::Vec<usize>>`

push_5(&mut num_cell.borrow_mut()); compiles.

push_5(num_cell.borrow_mut().as_mut()); does too

Upvotes: 5

Related Questions