Is datatypes are infered automatically by compiler in rust?

let mut a = 100;
let mut foo:&mut i32 = &mut a;
let mut bar:&mut &mut i32 = &mut foo;
let mut opt:Option<&mut &mut i32> = Some(&mut bar);
//let barfoo = *opt.as_mut().expect("");//line 5
let barfoo:&mut i32 = *opt.as_mut().expect("");//line 6

Above code is giving compilation error at line no 5
line no 5 - this line gives compilation error .Here I haven't declared opt type explicitly.
line no 6 - this line is exactly same as line 5 , only difference here is that I have declared opt type explicitly as &mut i32.
Similar behavior is in rust-playground as well .

AFAIK unlike c & c++ (ignore auto & decltype which is in C++) in rust there is no such restriction of specifying dataypes explicitly and datatypes are inferred by compiler automatically. Then why line no 5 is failing?

No, this is not true as-is. Sometimes the compiler can't infer types, and sometimes it will not infer types purposefully (eg. function signatures).

this is surprising, I usually avoid specifying types thinking that compiler will infer it for me. Is there any documentation on which situation compiler will not guess the types?

The mutable reference type is not Copy, since it must have exclusive access to its target. Instead, they can be reborrowed, which is an operation that creates a "sub-reference" to the same value. When reborrowing, exclusive access it guaranteed by making the original reference unusable until the last use of the sub-reference.

Reborrowing will sometimes happen implicitly — this makes mutable references behave very similar to types that are Copy, since reborrowing behaves similarly to copying of types that are Copy. However, reborrowing will only happen implicitly if the target type is known without the compiler having to do any inference. Otherwise, the mutable reference behaves like any other non-Copy type. This is what you are seeing — in one case the target type is known and an implicit reborrow happens. In the other case, no implicit reborrow happens and it fails since the type cannot be copied.

You can explicitly insert a reborrow with &mut *the_mutable_reference. In your case, that looks like this:

let barfoo = &mut **opt.as_mut().expect("");

To be clear, this is not a failure to infer the type of barfoo. Rather, its a failure to insert an implicit reborrow operation.

5 Likes

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.