rust-lang / rust-lang/reference
Documentation on lifetime extension is confusing (and in a confusing location)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 1.6k
- Forks
- 607
- PR merge metrics
- PR metrics pending
Description
See here for some context:
The reference says about lifetime extension
If a borrow, dereference, field, or tuple indexing expression has an extended temporary scope then so does its operand. If an indexing expression has an extended temporary scope then the indexed expression also has an extended temporary scope.
I read this 5 times and still didn't know what it was supposed to tell me. Thankfully, @m-ou-se came to the rescue. :)
Temporary lifetime extension today always involves: a let statement, a & borrow expression in there, a temporary (e.g. temp()) inside of that.
trivial example is
let a = &temp();There is a set of operations that you can put between the let and &: borrow, cast, tuple expression, braced struct expression, array expression, or block expression. e.g. let a = {[(&temp() as _,)]}; will extend temp().
There is a set of operations that you can put between the & and the temporary: borrow, dereference, field, tuple index, or index expression. e.g. let a = &temp().field.0[1]; will extend temp().combined example is let a = Some { 0: &temp().field };
So the algorithm is: from the initializer expression, traverse through borrows, cast, tuple, braced struct, array, block until we hit an &. Then traverse further through place projections. Then extend that.
The docs currently describe the inner part first. Also it is not clear what it means that "if a field expression has extended scope then so does its operand" -- really it's the operand that gets lifetime extended, and then the field of course inherits the lifetime from its base place.
And finally I think the location in the docs where this is discussed is confusing: this is explained in the page about destructors, but lifetime extension is relevant even without drop -- like when one creates a raw pointer to some memory and then later needs to be sure the memory the pointer points to is still live.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Rust Reference section that currently explains lifetime extension under destructors, then review the linked discussion for the proposed traversal order and examples. Rework the explanation so the initializer-to-borrow path and subsequent place projections are clear, and move or contextualize it so lifetime extension is not presented as relevant only to destructors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100