GAT `type Assoc<T: ?Sized>` implicitly requires `Self` to be `'static`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
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 https://github.com/rust-lang/rust/issues/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
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.
Research direction
Start by reproducing the examples from crates/sandbox/src/main.rs with rustc 1.81.0, including the dyn Layout, dyn Layout + 'static, and dyn Layout + '_ variations. Read the related discussion in issue #87479 and determine whether the implicit lifetime behavior is intended or a compiler bug; done should include a resolved explanation or a clearly scoped compiler change.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100