Skip to content

mGCA: Type-level free & assoc const paths don't induce trait object lifetime defaults #151649

@fmease

Description

@fmease

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<'_>`

Metadata

Metadata

Assignees

Labels

A-dyn-traitArea: trait objects, vtable layoutA-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.F-generic_const_items`#![feature(generic_const_items)]`F-min_generic_const_args`#![feature(min_generic_const_args)]`S-blockedStatus: Blocked on something else such as an RFC or other implementation work.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions