Why does Rust handle unborrowing only lazily?


#1

Hello,

I really fell in love with Rust the last few weeks, since it has a really nice type system and many features of a modern programming language. Especially the ownership system is really great!
I stumbled upon one thing I don’t quite know any reasoning for yet. I have this piece of code as a minimal example:

fn f() -> Vec<i32> {
    let result = vec![1, 2, 3, 4, 5];
    let x = result.first().expect("Error");
    println!("{}", x);
    return result;
}

fn main() {
    let v = f();
    println!("{:?}", v);
}

It does not compile, and the error is the following:

error[E0505]: cannot move out of `result` because it is borrowed
 --> src/main.rs:5:12
  |
3 |     let x = result.first().expect("Error");
  |             ------ borrow of `result` occurs here
4 |     println!("{}", x);
5 |     return result;
  |            ^^^^^^ move out of `result` occurs here

The toolchain used to build was

nightly-x86_64-unknown-linux-gnu (default)
rustc 1.28.0-nightly (86a8f1a63 2018-06-17)

So apparently, the variable x is only freed after the function is completed. And therefore the borrow is still active on the return statement, which leads to above error. But obviously, the variable is not used after the println, so it could be freed before the return statement. Then, the vector result would not have any active borrow, and the code would compile totally fine.
I wonder if there is a plan to make borrow checking more dynamic like this? Or is there a reason against that?

Kind regards,
ISibboI


#2

There is the unstable feature called non lexical lifetimes that does exactly what you are saying.

In practice at the actual state, the only way to do so is putting x and the print inside a scope. This is because the borrowck does not know that x is not used after the print, even if this is obvious for us.

You can try that your example is working using #![feature(nll)] with the nightly you are already using. Said that, I am not aware of the actual problems of this new feature, and when we can expect to land on stable :slightly_frowning_face:.


#3

Perfect thanks! That was exactly what I was looking for!
I hope it gets integrated into the stable release soon :slight_smile:


#4

Niko wrote a blog post last week about the current status of the NLL feature, if you’re curious. Basically, it’s nearly feature complete (at least for the scope of the first version), they just need to work on performance and diagnostics some more :slight_smile:


#5

Thank you, that’s an awesome post! Now I feel I can trust the nightly feature enough to just use it.