Description
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.
#![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)
.