I've had enough experience with Rust that I rarely get stuck on borrow-checking issues, but there is one mistake I've made a couple of times that has had me confused for a long time before I eventually realized what was going on.
The code below fails to compile:
struct Wrapper<'a, T> {
inner: &'a mut T,
}
impl<'a, T> Wrapper<'a, T> {
fn new(inner: &'a mut T) -> Self {
Self { inner }
}
fn reborrow(&mut self) -> Wrapper<'_, T> {
Self { inner: self.inner }
}
}
With an error like:
error: lifetime may not live long enough
--> test.rs:11:23
|
5 | impl<'a, T> Wrapper<'a, T> {
| -- lifetime `'a` defined here
...
10 | fn reborrow(&mut self) -> Wrapper<'_, T> {
| - let's call the lifetime of this reference `'1`
11 | Self { inner: self.inner }
| ^^^^^^^^^^ this usage requires that `'1` must outlive `'a`
The mistake here is that using Self in the reborrow method refers not just to Wrapper but specifically to Wrapper<'a, T>, with a different lifetime than intended.
Changing it to this resolves the problem:
fn reborrow(&mut self) -> Wrapper<'_, T> {
Wrapper { inner: self.inner }
}
As now the lifetime will be inferred to the intended value.
Any thoughts on how the compiler could catch this kind of mistake or make it more obvious what is happening, without spurious warnings?
15 Likes
djc
September 28, 2025, 7:37pm
2
Worth a diagnostics issue if there isn’t one already. Definitely an issue that has stumped me a few times.
2 Likes
opened 09:49PM - 03 Sep 22 UTC
A-diagnostics
A-lifetimes
T-compiler
A-suggestion-diagnostics
D-newcomer-roadblock
Heads-up: [PR 100976](https://github.com/rust-lang/rust/pull/100976) probably fi… xes this but I still felt its own issue was warranted (and didn't find an existing one).
---
[Given the following code:](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0bf33196179908c605f448226b34ea53)
```rust
pub struct Path<'a> {
string: &'a mut String,
}
impl<'a> Path<'a> {
pub fn sub(&mut self) -> Path/*<'_>*/ {
Self {
string: self.string,
}
}
}
```
The current output is:
```
error: lifetime may not live long enough
--> src/lib.rs:8:21
|
5 | impl<'a> Path<'a> {
| -- lifetime `'a` defined here
6 | pub fn sub(&mut self) -> Path/*<'_>*/ {
| - let's call the lifetime of this reference `'1`
7 | Self {
8 | string: self.string,
| ^^^^^^^^^^^ this usage requires that `'1` must outlive `'a`
```
Ideally the output should look like:
```
7 | Self {
| ^^^^ help: Consider replacing `Self` with `Path`
```
Programmers not-infrequently [expect `Self` to act as a type constructor](https://users.rust-lang.org/t/rewrite-generics-parameter-of-self/80347/6) and not fully aliased type (including lifetimes). Using `Path` in this context infers the lifetime, whereas using `Self` make the lifetime exactly `'a`.
Though I haven't included it in my example, consider also the case when `Self` is used as the return type.
[Another recent URLO example which inspired this report.](https://users.rust-lang.org/t/implement-a-stack-of-path-component-with-a-shared-buffer/80666)
The same error appears on stable, nightly, and beta. But see [PR 100976](https://github.com/rust-lang/rust/pull/100976) which may resolve this issue.
@rustbot label +A-lifetimes +A-suggestion-diagnostics +D-newcomer-roadblock
The PR mentioned at the top didn't land.
9 Likes