impl-trait-goals
impl-trait-goals copied to clipboard
Fully-Explicit Syntax
The general goal of this issue is to be able to name an impl Trait
type.
@aturon sketched out a strawman for this in their expanded impl Trait
RFC. The proposed syntax was abstype Foo: SomeTrait
.
@eddyb explained their preference for the type Foo = impl Trait
syntax here.
I will continue to prefer using a regular type alias with regular impl Trait
syntax until someone shows a need for something you can't express using that.
One thing that should also be resolved as a part of this is figuring out which type and lifetime parameters are in scope for a type-aliased impl Trait
, and how those parameters should be treated. There's some discussion of this here, but I think there are more interactions to be examined. For example:
trait Foo<'a> {
type Bar;
fn foo() -> Self::Bar;
}
impl<'a> Foo<'a> for i32 {
type Bar = impl Debug;
fn foo() -> Self::Bar {
42
}
}
In this example, I'd presume that 'a
is in scope for type Bar = impl Debug;
. I'd expect that to mean that <i32 as Foo<'a>>::Bar
would NOT unify with <i32 as Foo<'b>>::Bar
. Is that what others would expect as well?
@cramertj I think the latest RFC wants impl Debug + 'a
specifically for lifetimes but otherwise yes.
@eddyb Ah, so, amended example:
trait Foo<T> {
type Bar;
fn foo() -> Self::Bar;
}
impl<T> Foo<T> for i32 {
type Bar = impl Debug;
fn foo() -> Self::Bar {
42
}
}
In this case, <i32 as Foo<String>::Bar>
wouldn't unify with <i32 as Foo<usize>::Bar>
. In order to make that happen, you'd need something like this:
trait Foo<T> {
type Bar;
fn foo() -> Self::Bar;
}
type MyBar = impl Debug;
impl<T> Foo<T> for i32 {
type Bar = MyBar;
fn foo() -> MyBar {
42
}
}