Today is one of those extremely rare days when I get blocked by borrow checker and I'm not sure if it is me who is wrong or borrow checker is not smart enough:
struct Container<'a>(&'a mut ());
impl Drop for Container<'_> {
fn drop(&mut self) {
todo!()
}
}
impl<'a> Container<'a> {
fn new_nested<'b>(&'b mut self) -> Container<'b>
where
'a: 'b,
{
Self(self.0)
}
}
fn foo() {
let mut v = ();
let mut c = Container(&mut v);
c.new_nested();
}
My reasoning here is that 'a
is a larger lifetime than 'b
, so 'b
will never outlive 'a
. But compiler disagrees:
error: lifetime may not live long enough
--> src/lib.rs:12:14
|
9 | impl<'a> Container<'a> {
| -- lifetime `'a` defined here
10 | fn new_nested<'b>(&'b mut self) -> Container<'b>
| -- lifetime `'b` defined here
11 | where 'a: 'b {
12 | Self(self.0)
| ^^^^^^ this usage requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
Adding 'b: 'a
is pointless though because it makes the whole thing unusable downstream:
error[E0597]: `c` does not live long enough
--> src/lib.rs:19:5
|
18 | let mut c = Container(&mut v);
| ----- binding `c` declared here
19 | c.new_nested();
| ^ borrowed value does not live long enough
20 | }
| -
| |
| `c` dropped here while still borrowed
| borrow might be used here, when `c` is dropped and runs the `Drop` code for type `Container`
I checked a bunch of similar-looking issues and even tried current version of Polonius on Nightly, can't figure it out