[Solved] Borrow doesn't drop? "returning this value requires that"


Hello, rustaceans!
I’m struggling with a problem, glad if someone explain it to me.
So, playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d06fcdc5d812895fd068176090288f1b

As you can see, code doesn’t compile, and complains about double mutable borrowing, though it’s clear that borrow on line 17 must be released on line 21? Why so? I understand that if I return something, it will block another borrow, for the lifetime of “something”, but I don’t understand why compiler doesn’t take in account “block” structure.


This was supposed to have been fixed as part of NLL, but was instead deferred to polonius (NLL++ :slight_smile:).


Oh, thank you very much, I thought there is a flaw in my logic I don’t understand.

So this is current limitation of rust? Any way I can solve this? Think even unsafe is no helper here. I can’t imagine of any workaround, only change logic completely.


Maybe you could work around it like this (+/- handling of edge cases)

let (first, rest) = self.stack.split_first_mut().unwrap();

let it = rest.last_mut().unwrap();
if it.el.l != 1 {
    return Ok(&mut it.el);

let el = &mut first.el;

Apart from that, lifetime hacks are doable with unsafe. You can transmute lifetimes (like this) or cast to a raw pointer and back.


Thank you very much for answer. Splitting vector solution gives me no help because in my project index can be arbitrary, and if if it.el.l != 1 { fail, I will have to traverse every other vector’s item.

Github link, though, I find very useful. Need to reed about on lifetime erasion.


It seem to be working!

Didn’t think transmute from vec to vec will give me something, but it actually worked!


But wait, there’s more! :slight_smile:

transmute in not necessary: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=309a50f9084ddfe48817c5b0b6753b17

I was trying to make such thing even before posting this question, it just I didn’t explicitly cast to raw mut pointer (it was like unsafe { &mut (*(&mut self.stack))[index] };), and thus not work.