Reborrow "function" vs reborrow operator

⚓ Rust    📅 2025-09-25    👤 surdeus    👁️ 7      

surdeus

Warning

This post was published 36 days ago. The information described in this article may have changed.

I'm trying to learn more about the details of reborrowing. There was a useful thread about reborrowing recently, but replies are locked. So I'll open a new thread.

Inside the linked thread was a link to a blog post. The blog post attempts to define reborrows in terms of a function:

fn reborrow<'a, 'b, T>(r: &'a mut &'b mut T) -> &'a mut T {
    r
}

In the same thread QuineDot mentions:

The links in their reply goes to a function foo:

fn foo(s: &mut String) -> &str {
    &**s
}

or:

fn foo(s: &mut String) -> &str {
    let ms: &mut str = &mut **s;
    let rs: &str = &*s;
    rs
}

Why is this distinction important? Is the idea that foo cannot be rewritten in terms of reborrow because the reborrow operator is special and can handle e.g. locals going out of scope?1

Additionally, why in the reborrow function, why is the language "the reference itself is borrowed," as opposed to reborrowed? My understanding of this function when called like e.g:

let mut bar = String::new();

let mut quux = &mut bar; // Avoid a temporary dropped error.
let baz = reborrow(&mut quux);

is something like this:

  1. quux has type &'b mut String. Create a temp binding for &'first mut quux.
  2. Immediately reborrow that temp binding, e.g. do (&'a mut *(&'first mut quux)). r has type &'a mut &'b mut String.
  3. The first/only expression in that function is to return s. The return type and s don't match. 4. Deref to match the nesting level of references. This gives us a &'b mut String.
  4. &'a mut String is a subtype of &'b mut String, so coerce to &'a mut String.
  5. s is moved to baz and s goes out of scope.
  6. When baz goes out of scope (lifetime 'a), the lifetime &'first introduced by the temp binding goes out of scope as well. quux binding is usable again.

Is the above more-or-less correct? If so, what makes the reborrow operators in foo (either version) have different semantics than what I just listed?1

  1. I hope I'm somewhat on the right track. Otherwise, I don't think I understand specifically why that section of QuineDots (very useful!) "Learning Rust" book is linked. I can't tell whether function foo itself is meant to compare-and-constrast directly with reborrow, or foo contains expressions/operators that a reborrow function cannot convey.

1 post - 1 participant

Read full topic

🏷️ Rust_feed