Skip to content

GAT: Self: 'a bound cannot be added for types which store a generic T that is further constrained by the impl #92280

Closed
@kahomayo

Description

@kahomayo

Within an impl<T: Trait1> Trait2 for Struct<T::Foo>, a GAT bound of Self: 'a does not compile, asking me to add an explicit T::Foo: 'a bound.

Playground

#![feature(generic_associated_types)]
#![allow(non_camel_case_types)]

trait HasAssoc {
    type Assoc;
}

trait Iterate<S: HasAssoc> {
    type Iter<'a> where Self: 'a;
    fn iter<'a>(&'a self) -> Self::Iter<'a>;
}

struct KeySegment_Broken<T>{ key: T }
impl<S: HasAssoc> Iterate<S> for KeySegment_Broken<S::Assoc> {
    type Iter<'a> where Self: 'a = ();
    fn iter<'a>(&'a self) -> Self::Iter<'a> {
        todo!()
    }
}

This code results in two errors:

   Compiling playground v0.0.1 (/playground)
error: `impl` associated type signature for `Iter` doesn't match `trait` associated type signature
  --> src/lib.rs:17:5
   |
9  |     type Iter<'a> where Self: 'a;
   |     ----------------------------- expected
...
17 |     type Iter<'a> where Self: 'a = ();
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found

error[E0309]: the associated type `<S as HasAssoc>::Assoc` may not live long enough
  --> src/lib.rs:17:36
   |
17 |     type Iter<'a> where Self: 'a = ();
   |                                 -  ^^ ...so that the type `KeySegment_Broken<<S as HasAssoc>::Assoc>` will meet its required lifetime bounds
   |                                 |
   |                                 help: consider adding a where clause: `, <S as HasAssoc>::Assoc: 'a`

I believe that the E0309 error is a bug, as since key is known in this impl to be S::String, S::String must outlive Self and the suggested bound should thus already be implied by Self: 'a. Applying the suggested fix removes this error, but obviously cannot compile (as the GAT impl now has a stricter where than in the trait declaration). The first error seems incorrect too, as there is no visible difference between the highlighted lines other than = ():

struct KeySegment_SuggestedFix<T>{ key: T }
impl<S: HasAssoc> Iterate<S> for KeySegment_SuggestedFix<S::Assoc> {
    // error: `impl` associated type signature for `Iter` doesn't match `trait` associated type signature
    type Iter<'a>
    where
        Self: 'a,
        S::Assoc: 'a
    = ();
    
    fn iter<'a>(&'a self) -> Self::Iter<'a> {
        todo!()
    }
}

Adding the type bound on the struct declaration avoids these errors, but is less generic.

struct KeySegment<S: OnceTypeSystem> { key: S::String }
impl<S: OnceTypeSystem> PathSegment<S> for KeySegment<S> {
    type Iter<'a> where Self: 'a = ();
    fn iter<'a>(&'a self) -> Self::Iter<'a> {
        todo!()
    }
}

Meta

rustc --version --verbose:

rustc 1.59.0-nightly (475b00aa4 2021-12-24)
binary: rustc
commit-hash: 475b00aa4037461b506539a06d15ca6091b461a7
commit-date: 2021-12-24
host: x86_64-pc-windows-msvc
release: 1.59.0-nightly
LLVM version: 13.0.0

I have also encountered this bug on 1.59.0-nightly (e100ec5bc 2021-12-21).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)C-bugCategory: This is a bug.F-generic_associated_types`#![feature(generic_associated_types)]` a.k.a. GATsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions