Downgrading a RefMut to a Ref


#1

Hi,

I’m afraid I’m missing something obvious here, but is it possible to convert a convert a RefMut<T> into a simple Ref<T>.

The reason I’m trying to do this, is that I have a RefMut<T>, but I’d like to pass it to a function that takes a Ref<T>. Here is a simplified example link to playground:

use std::cell::{Ref, RefCell};

// This function only needs a reference to an u8
fn take_ref(_: Ref<u8>) {}

fn main() {
    let my_var = RefCell::new(0);

    let mut mut_ref = my_var.borrow_mut();
    // do stuff that mutates my_var
    // [..]

    // Now I'd like to pass `my_var` to a function that only need a reference
    take_ref(mut_ref)
}

That does not work unfortunately. The reason I was expecting this to work is that similar code without RefCell just works:

// This function only needs a reference to an u8
fn take_ref(_: &u8) {}

fn main() {
    let mut my_var = 0;

    let mut mut_ref = &mut my_var;
    // do stuff that mutates my_var
    // [..]

    // Now I'd like to pass `my_var` to a function that only need a reference
    take_ref(mut_ref)
}

If I’m not mistaken, this works because &mut T implements Borrow<T> (or is it because of some AsRef<T> impl? Not sure). But it appears that RefMut<T> does not implement Borrow<Ref<T>>, so I guess I have to explicitely downgrade RefMut<T> into Ref<T>, but I don’t know how.


#2

Why does take_ref need to take a Ref<u8> specifically rather than just a &u8?


#3

ooh, you’re right this just works:

use std::cell::{Ref, RefCell};

fn take_ref(_: &u8) {}

fn main() {
    let my_var = RefCell::new(0);

    let mut mut_ref = my_var.borrow_mut();
    // do stuff that mutates my_var
    // [..]

    take_ref(&mut_ref)
}

I chose Ref<T> because since I was working with a RefCell, I was putting Ref<T> where I would have used &T and RefMut<T> where I would have used &mut T. My reasoning was that these are strictly equivalent, one at compile time, and the other one at runtime.


#4

Ref and RefMut are generally only needed if you need to return them from an fn. If you need access to their inner value while the Ref or RefMut is still live/active, then you can use their inner value as a reference directly.