Open
Description
I tried this code:
trait Layout {}
trait Desc {
type Children<A: ?Sized>;
fn stage(_children: &Self::Children<dyn Layout>);
}
fn stage<D: Desc>(children: D::Children<dyn Layout>) {
D::stage(&children);
}
This doesn't compile with two errors, and I can't explain why:
error[E0310]: the parameter type `D` may not live long enough
--> crates/sandbox/src/main.rs:68:5
|
68 | D::stage(&children);
| ^^^^^^^^^^^^^^^^^^^
| |
| the parameter type `D` must be valid for the static lifetime...
| ...so that the type `D` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound
|
67 | fn stage<D: Desc + 'static>(children: D::Children<dyn Layout>) {
| +++++++++
error[E0597]: `children` does not live long enough
--> crates/sandbox/src/main.rs:68:14
|
67 | fn stage<D: Desc>(children: D::Children<dyn Layout>) {
| -------- binding `children` declared here
68 | D::stage(&children);
| ---------^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `children` is borrowed for `'static`
69 | }
| - `children` dropped here while still borrowed
Why is the D
required to be 'static
here?
Why does the &children
need to have a 'static
lifetime here as well?
Here are variations that do compile, but I also can't explain why they compile:
Adding `dyn Layout + 'static` in the trait definition
trait Layout {}
trait Desc {
type Children<A: ?Sized>;
fn stage(_children: &Self::Children<dyn Layout + 'static>);
}
fn stage<D: Desc>(children: D::Children<dyn Layout>) {
D::stage(&children);
}
Adding `dyn Layout + '_` in the trait definition
trait Layout {}
trait Desc {
type Children<A: ?Sized>;
fn stage(_children: &Self::Children<dyn Layout + '_>);
}
fn stage<D: Desc>(children: D::Children<dyn Layout>) {
D::stage(&children);
}
This variation doesn't compile, but it removes the `D` must be valid for the static lifetime
error and I also don't understand why that is:
trait Layout {}
trait Desc {
type Children<A: ?Sized>: 'static;
fn stage(_children: &Self::Children<dyn Layout>);
}
fn stage<D: Desc>(children: D::Children<dyn Layout>) {
D::stage(&children);
}
There is definitely something implicit going on here which I don't know. Some helpful people suggested this may be related to #87479, but I don't see how.
@nikomatsakis do you have an idea if this is related? Is this some compiler bug or smth not documented?
Meta
rustc --version --verbose
:
rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: x86_64-unknown-linux-gnu
release: 1.81.0
LLVM version: 18.1.7