I was learning Rust and all the references and borrowing stuff when I came across this weird case:
fn main() {
let mut n = 42u32;
let ref1 = &mut n;
let ref2 = ref1; // line 5
ref2;
ref1; // line 8
}
This snippet does not compile since ref1
is moved in line 5 and can not be used in line 8, which I understand.
But when I added a type annotation (which seems totally extraneous and should not affect anything at all since rust-analyzer
reports the exactly same type) to ref2:
fn main() {
let mut n = 42u32;
let ref1 = &mut n;
let ref2: &mut u32 = ref1;开发者_如何学Go
// ++++++++++
ref2;
ref1;
}
It suddenly compiles! (You can try it at the playground)
What is going on? I am currently using rustc 1.65.0, is this some kind of bug? Or is there something I missed?
I tried this using different version of rustc in Compiler Explorer and it seems that 1.36.0 is the first version that successfully compiles the second snippet. So I checked the annocement and noticed they introduced something called 'Non-Lexical Lifetimes' in that version, I am not sure whether this is relevant but I noticed the error msg from rustc 1.35.0 is:
error[E0505]: cannot move out of `ref1` because it is borrowed -->
<source>:9:5
|
6 | let ref2: &mut u32 = ref1;
| ---- borrow of `*ref1` occurs here
...
9 | ref1;
| ^^^^ move out of `ref1` occurs here
error: aborting due to previous error
which is different from the error for the first snippet that basically says that you can not use ref1
after it is moved. How can I understand this?
精彩评论