A question about the mutable reference syntax

So let's say I have two arbitrary functions defined as shown in the snippet below:

fn x<T>(dat: &mut T) {
    y(&mut dat)
}
fn y<T>(dat: &mut T) {
    // do_something();
}

The above would obviously error with 'cannot borrow as mutable'.
Now only if we change the definition of x to the following:

fn x<T>(mut dat: &mut T) {
    y(&mut dat)
}

it would be valid. Isn't the syntax here queer? I have already borrowed the item as mutable then why write mut dat: &mut T?

Since the dat has type &mut T, &mut dat has type &mut &mut T. That's why you need to mut specifier on the dat variable itself. Note that the y(&mut dat) will be desugared into y::<&mut T>(&mut dat) so it will takes &mut &mut T.

1 Like

Is this an example of deref coercion in action? (&mut &mut T -> &mut T )

deref coercion could be used here, but not in this exact code, because y is generic and its type parameter T is not known from other places.

From inside x, calling y::<T>(&mut dat) and y::<T>(dat) should both work equivalently, and that's due to deref coercion. With the explicit type, the type to coerce to is known.

It is merely an example of the T being a different type in each function. If x is called with T = u32, then it will call y with T = &mut u32.

2 Likes

Try this:

fn x<T>(dat: &mut T) {
    y(dat)
}
fn y<T>(dat: &mut T) {
    // do_something();
}

If it surprises you that this works, consider a slightly altered example:

fn x<T>(dat: &mut T) {
    y(dat);
    y(dat)
}
fn y<T>(dat: &mut T) {
    // do_something();
}

Still works! We aren't interested in borrowing from &mut T; we can simply pass the borrow by value, and it does the right thing.

If you do want to mutably borrow dat, then the binding needs to be mutable.

2 Likes

I just realized how silly this question was! Makes complete sense! But the mut x: &mut T thing still strikes me a bit queer.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.