Non-lexical lifetimes based on liveness


I think what you want is to be able to express a function signature that takes an immutable borrow (index) and a mutable borrow (self) with a promise it won’t start using the mutable borrow before it stops using the immutable one. From what I know, the NLL will change only how the bodies of function work, the meaning of function signatures will remain unchanged. The extension to function signatures that you want might be possible when the proposed two-stage borrows would get exposed in the typesystem, alghough I’m not sure about it. Also exposing two-stage borrows would increase the complexity of the language significantly.

The current solution to such safe indexes is to use closure to generate the fresh lifetime for indices. Check out the indexing crate and the @Gankro’s playground.

But from what I understand, these solutions don’t allow a mutable method to consume multiple independent indexes. I think that a good workaround for these would be for the closure to return an operation – playground prototype. Note that I’m certainly not an expert wrt. variance etc. so my code may not be sound.


Yes, thats exactly what I would like to do! Your wording is much better :slight_smile: Thanks also for the links to the code, its very interesting — I’ll play around with it, and maybe get inspired.

After reading the blog post few more times I believe that you are right, and that the analysis of the lifetime seems to stop at the method boundary (in theory, it doesn’t have to, but that would call for a more complex graph analysis). However, if I understand it correctly, the current proposal should allow for destructuring the index in the function signature, e.g.:

fn consume<'a, 'b: 'a>(&'b mut self, (internal_index:UnsafeIndex, _): Index<'a>)

The idea here is that index is dropped (and the associated lifetime/phantom borrow is released) before the method is called. The ‘safe’ index could then be encoded as a tuple of an ‘unsafe’ index + a marker.


Maybe related, would it make sense to also enable idiom like if let Some(x) = y && x? That is, bring matched values in scope of further parts of the condition?


That will be parsed like if let Some(x) = (y && x). There would have to be some way to group the left side that you intend, like if (let Some(x) = y) && x, which looks strange. That would mean something like "let in expression context returns a bool"? Might be neat to generalize if-let and while-let.


That looks very much like using pattern guards. There is an open RFC issue for it.