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.
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.
If you try to use bytes after the immutable call, it fails even with NLL:
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.
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.