Understanding the typing of references

Hi everybody,
While going through the Rust tutorial and its borrow-checker, I looked at some examples and played with them. There is still one that I do not understand why it is accepted, that I paste just below. It passes the type checks and compiles correctly, which shows that Rust unifies &i32 with &&mut i32; I read that Rust does auto dereferencing for method calls, but I read nowhere that it does so for let bindings. Can anyone explain me how this works in Rust ? Thanks in advance.


fn foo<'a>(t0: &'a mut i32         ) -> i32 {
    let t2: & &mut i32 = &t0;
    let q: & i32 = &*t2;    --strange type here, it still works (as if a Deref kicks in here)
    return *q;
}

fn bar<'a>(t0: &'a mut i32         ) -> i32 {
    let t2: & &mut i32 = &t0;
    let q: & &mut i32 = &*t2;    
    return **q;
}

fn main() {
    let mut i8934 : i32 = 42;
    let mut t0 : &mut i32 = &mut i8934;
    let ret : i32 = foo(t0);
    
    let mut i8935 : i32 = 44;
    let mut t1 : &mut i32 = &mut i8935;
    let ret2 : i32 = bar(t1);
    println!("{} {}", ret, ret2);
    
}

This thread will help: Why does this compile? Automatic dereferencing?

Thanks. Indeed, Why does this compile? Automatic dereferencing? - #13 by mbrubeck explains it well (and we have impl<'a, T> Deref for &'a mut T ). Is there any reason for these features to be allowed in Rust except faster code writing ?

Yeah, I believe it's for ergonomic reasons.

This SO question can be useful for you.

Thanks a lot, that answers pretty much to my questions.