This is the assoc const version of #115379 (assoc tys).
Blocking this on PR #129543 which provides fundamental fixes and the necessary framework.
The following snippets should all compile but don't:
Reproducer [1/5] (self ty)
#![feature(min_generic_const_args)]
#![expect(incomplete_features)]
trait Trait<'a>: 'a { type const K: usize; }
trait Bound {}
impl<'a> Trait<'a> for dyn Bound + 'a {
type const K: usize = 0;
}
fn f<'r>(x: [(); <dyn Bound + 'r as Trait<'r>>::K]) { g(x) }
fn g<'r>(_: [(); <dyn Bound as Trait<'r>>::K]) {}
error[E0759]: `fn` parameter has lifetime `'r` but it needs to satisfy a `'static` lifetime requirement
--> q.rs:13:13
|
13 | fn g<'r>(_: [(); <dyn Bound as Trait<'r>>::K]) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| this data with lifetime `'r`...
| ...is used and required to live as long as `'static` here
error: lifetime may not live long enough
--> q.rs:13:1
|
13 | fn g<'r>(_: [(); <dyn Bound as Trait<'r>>::K]) {}
| ^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | |
| | lifetime `'r` defined here
| requires that `'r` must outlive `'static`
Reproducer [2/5] (trait ref in qpath)
#![feature(min_generic_const_args)]
#![expect(incomplete_features)]
trait Trait<'a, T: 'a + ?Sized> { type const K: usize; }
fn f<'r, T: Trait<'r, dyn Bound + 'r>>(x: [(); <T as Trait<'r, dyn Bound + 'r>>::K]) { g::<T>(x) }
fn g<'r, T: Trait<'r, dyn Bound + 'r>>(_: [(); <T as Trait<'r, dyn Bound>>::K]) {}
trait Bound {}
error[E0308]: mismatched types
--> src/lib.rs:7:43
|
7 | fn g<'r, T: Trait<'r, dyn Bound + 'r>>(_: [(); <T as Trait<'r, dyn Bound>>::K]) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
|
= note: expected trait `Trait<'r, (dyn Bound + 'static)>`
found trait `Trait<'r, (dyn Bound + 'r)>`
note: the lifetime `'r` as defined here...
--> src/lib.rs:7:6
|
7 | fn g<'r, T: Trait<'r, dyn Bound + 'r>>(_: [(); <T as Trait<'r, dyn Bound>>::K]) {}
| ^^
= note: ...does not necessarily outlive the static lifetime
error: lifetime may not live long enough
--> src/lib.rs:6:88
|
6 | fn f<'r, T: Trait<'r, dyn Bound + 'r>>(x: [(); <T as Trait<'r, dyn Bound + 'r>>::K]) { g::<T>(x) }
| -- lifetime `'r` defined here
Reproducer [3/5] (GAC (GCI) with own lifetime)
#![feature(generic_const_items, min_generic_const_args)]
#![expect(incomplete_features)]
trait Trait { type const K<'a, T: 'a + ?Sized>: usize; }
fn f<'r, T: Trait>(x: [(); <T as Trait>::K::<'r, dyn Bound + 'r>]) { g::<T>(x) }
fn g<'r, T: Trait>(_: [(); <T as Trait>::K::<'r, dyn Bound>]) {}
trait Bound {}
error[E0521]: borrowed data escapes outside of function
--> src/lib.rs:6:70
|
6 | fn f<'r, T: Trait>(x: [(); <T as Trait>::K::<'r, dyn Bound + 'r>]) { g::<T>(x) }
| -- - ^^^^^^^^^
| | | |
| | | `x` escapes the function body here
| | | argument requires that `'r` must outlive `'static`
| | `x` is a reference that is only valid in the function body
| lifetime `'r` defined here
dyn Bound in g's signature currently elaborates to dyn Bound + 'static but it should elaborate to dyn Bound + 'r since (resolved) assoc consts should be eligible containers and induce trait object lifetime defaults to its constituent types.
Reproducer [4/5] (GAC (GCI) with parent lifetime)
#![feature(generic_const_items, min_generic_const_args)]
#![expect(incomplete_features)]
trait Trait<'a> { type const K<T: 'a + ?Sized>: usize; }
fn f<'r, T: Trait<'r>>(x: [(); <T as Trait<'r>>::K::<dyn Bound + 'r>]) { g::<T>(x) }
fn g<'r, T: Trait<'r>>(_: [(); <T as Trait<'r>>::K::<dyn Bound>]) {}
trait Bound {}
error[E0521]: borrowed data escapes outside of function
--> src/lib.rs:6:74
|
6 | fn f<'r, T: Trait<'r>>(x: [(); <T as Trait<'r>>::K::<dyn Bound + 'r>]) { g::<T>(x) }
| -- - ^^^^^^^^^
| | | |
| | | `x` escapes the function body here
| | | argument requires that `'r` must outlive `'static`
| | `x` is a reference that is only valid in the function body
| lifetime `'r` defined here
Reproducer [5/5] (free GCI)
#![feature(generic_const_items, min_generic_const_args)]
#![expect(incomplete_features)]
type const K<'a, T: 'a + AbideBy<'a> + ?Sized>: usize = 0;
struct X<'r>([(); K::<'r, dyn Bound>]);
trait Bound {}
trait AbideBy<'a> {}
impl<'a> AbideBy<'a> for dyn Bound + 'a {}
error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src/lib.rs:6:14
|
6 | struct X<'r>([(); K::<'r, dyn Bound>]);
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'r` as defined here...
--> src/lib.rs:6:10
|
6 | struct X<'r>([(); K::<'r, dyn Bound>]);
| ^^
= note: ...but the lifetime must also be valid for the static lifetime...
note: ...so that the types are compatible
--> src/lib.rs:6:14
|
6 | struct X<'r>([(); K::<'r, dyn Bound>]);
| ^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `AbideBy<'r>`
found `AbideBy<'_>`
This is the assoc const version of #115379 (assoc tys).
Blocking this on PR #129543 which provides fundamental fixes and the necessary framework.
The following snippets should all compile but don't:
Reproducer [1/5] (self ty)
Reproducer [2/5] (trait ref in qpath)
Reproducer [3/5] (GAC (GCI) with own lifetime)
dyn Bounding's signature currently elaborates todyn Bound + 'staticbut it should elaborate todyn Bound + 'rsince (resolved) assoc consts should be eligible containers and induce trait object lifetime defaults to its constituent types.Reproducer [4/5] (GAC (GCI) with parent lifetime)
Reproducer [5/5] (free GCI)