Ignoring references to references question


#1

So reading a thread that blew up on on Friday, I didn’t realize that if I have a reference, and pass a reference to that reference the compiler will ignore one of those references. So this works fine:

fn foo(x : &u32) {
}

fn bar(y : &u32) {
    foo(&y)
}

This got me wondering if I should be passing &y or just y, passing &y helps the “local readability” I don’t need to track down the definition for y. But then when playing around this I noticed that when passing mutability references I would have to declare y as mutable, i.e.

fn foo(x :&mut u32) {
}

fn bar(mut y : &mut u32) {
    foo(&mut y)
}

Which it really isn’t…I’m kind of curious as to why these are different? There would have to be “special” compiler to code to detect that the reference to a references is not needed, I’d assume that similar “special” code would be included for the mutable references?


#2

Thinking about this a little more, I’m thinking I should avoid letting the compiler remove superfluous references since at some point a function might change from:

fn foo(x : &mut u32) {
}

to:

fn foo(x : &mut &mut u32) {
}

For some strange reason, then I would have to search for all the calls to the method to ensure the correct thing was happening.

I’m not sure I can think of a situation where a non mutable reference would change to a non mutable reference of a non mutable reference…So I guess “accidentally” passing a non mutable reference to a non mutable reference wouldn’t cause issues down the line.


#3

If you want to take an &mut reference to something, it has to be declared mut. Taking a mutable reference to an immutable value isn’t possible. Remember, let y: &mut i32; is an immutable binding to a mutable reference, and &mut y is then creating an immutable binding to y, in other words, &mut y is of type &mut &mut i32.