Borrow checker too strict. Will this be solved via NLL?


#1

Quite often, I see the following pattern.

https://play.rust-lang.org/?gist=315e3568533e70ff603194aa4f800531&version=nightly

It would be safe for the compiler to accept this but the borrow checker is unhappy.

In a nutshell, a struct’s method requires borrowing self mutably.
The result borrows self but immutably. The borrow checker extends the mutable borrow to the lifetime of the result.

The example here seem contrived, but I met this in real life.
For instance, in the fst crate (a finite state transducer crate. If you are unfamiliar with FST, it would be the same with a trie) , .next() modifies a buffer containing the and returning a reference to that buffer.

  • Will this example be solved by NLL?
  • Has it bothered other people?
  • Is there a way to workaround it simply?

#2

NLL does not address this. Yeah it comes up - just discussed this a few days ago.


#3

I just tried it on the playground link with #![feature(nll)] and it compiles without error…


#4

That’s cause bytes is unused after but I doubt that’s the real case.


#5

Seems to be working for me, even if bytes is used. I was expecting it to fail and trying to reason out why it couldn’t work, but it seems to be working fine.


#6

If you try to use bytes after the immutable call, it fails even with NLL:
https://play.rust-lang.org/?gist=c75709ea4cf190b7b7c83590cb6a8ea7&version=nightly

error[E0502]: cannot borrow `incrementor` as immutable because it is also borrowed as mutable
  --> src/main.rs:38:9
   |
37 |         let bytes: &[u8] = incrementor.inc();
   |                            ----------- mutable borrow occurs here
38 |         incrementor.whatever_with_immutable_borrow();
   |         ^^^^^^^^^^^ immutable borrow occurs here
39 |         bytes;
   |         ----- borrow later used here

This is a case where you might want mutable->immutable downgrades from the inc() call.


#7

What code did you try? This fails.


#8

I was using bytes before the incrementor.whatever_with_immutable_borrow() call.


#9

Yeah so that’s what the non-lexical part will fix - the scope of the borrow isn’t the lexical region of bytes but is actually tracked more precisely by the compiler. So this bit is fixed by NLL but now I’m not sure which exact scenario @fulmicoton is referring to - this or being able to downgrade a mutable borrow to immutable.


#10

I am more interested in the downgrading from mutable borrow to immutable borrow but that is still good to know!