better documentation of reborrowing
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 42/100
- Issue type
- Documentation
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- rust
- Domain
- documentation
Research direction
Start with the Reference's raw-pointer section and its implicit-borrows section, then review the related unfinished NLL discussion in #290. Determine where mutable-reference reborrowing belongs and ensure the documentation explains the provided typed and untyped examples, including when a mutable reference is moved versus reborrowed.
Written by the indexing model from the issue text.
Description
tl;dr: Rust documentation is unclear on reborrowing, should explain details in the Reference
As it stands, there is only one mention of "reborrowing" in the Reference, in this section on raw pointers. This only refers to reborrowing pointers, and not references, which is important in understanding how Rust handles mutable references (often implicitly reborrowing them instead of moving them). There is also some documentation on implicit borrowing, but again, this is sparse and does not cover reborrowing in the context of mutable references.
A key example of the implicit borrowing which confused me is the following:
fn main() {
let mut x = vec![1, 2, 3];
let y = &mut x;
let z: &mut Vec<i32> = y;
z.push(4);
y.push(5);
}
This code compiles fine, and x, as expected, becomes [1, 2, 3, 4, 5]. Initially, this code was unclear to me, but I was able to understand how it worked learning about both reborrowing and non lexical lifetimes. However, along the way I became familiar with how little documentation there is on the former. Questions have come up on the topic frequently, like this Reddit post from 2016, this post from 2018 on the Rust forums, more Reddit posts from 2018 and 2019, and in this forum post from January, which I found extremely helpful. A few of the discussions in these posts reference sources to reborrowing, but the only official documentation which was available is an earlier version of the Rustonomicon. There are some instances of the author of The Rust Programming Language, such as here, here, and in https://github.com/rust-lang/rust/issues/25899, mentioning adding reborrowing to the new book, but it seems that has been abandoned since: see https://github.com/rust-lang/book/issues/2144.
This concept is counter-intuitive to beginners, as it seems to violate the idea that there can only be one mutable reference to an object in a given scope. It also raises frequent forum questions, which become an effective way to get answers, but only due to the lack of documentation. Because of this, I think that some proper documentation on reborrowing is necessary. It would explain some of the quirks of this system, as choosing whether or not to reborrow is a decision made by the compiler, and can lead to some strange compilation errors without understanding this concept. For example,
let mut x = vec![1, 2, 3];
let y = &mut x;
let z = y;
will move y into z, but substituting the last line for
let z: &mut _ = y;
will reborrow y, since the compiler has to guarantee that z is &mut T. y can be freely used after the second case, but not at all after the first case. Rust has also made some progress with reborrowing, as issues like reborrowing in match arms which failed to compile in the past now work fine, without the need to force a move. The compiler can infer when it is necessary to move a &mut instead of reborrow it, but the logic behind this decision should be made clear to the programmer so that there is a better understanding of the final product.
It seems like there was some effort to document this topic (through non-lexical lifetimes) in #290. This documentation is unfinished, potentially due to the in-progress nature of non-lexical lifetimes, but the feature is stable, which means it could accompany a discussion of reborrowing. I think reborrowing is an important enough topic to get covered in some official documentation, and if not the book, then the reference should expand upon this technique.
- Dominant language
- Rust
- Stars
- 1.6k
- Forks
- 607
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 12
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.
More from rust-lang/reference
-
A-const-eval A-undefined-behavior
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
A-resolve
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
-
A-coercions
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
All issues in rust-lang/reference
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100