I'm using the specialization feature and got an error like this:
#![feature(specialization)]
#![feature(min_specialization)]
trait Foo {
type Ty;
fn foo() -> Self::Ty;
}
impl Foo for i32 {
type Ty = f32;
fn foo() -> Self::Ty {
1.0
}
}
impl<T> Foo for T {
default type Ty = ();
default fn foo() -> Self::Ty {
()
}
}
And the error message is:
error[E0308]: mismatched types
--> src/main.rs:21:9
|
18 | default type Ty = ();
| --------------------- expected this associated type
19 |
20 | default fn foo() -> Self::Ty {
| -------- expected `<T as Foo>::Ty` because of return type
21 | ()
| ^^ expected associated type, found `()`
|
= note: expected associated type `<T as Foo>::Ty`
found unit type `()`
It seems that the compiler didn't recognize that <T as Foo>::Ty is ().
I don't understand , why an impl could affect the default function? It looks to me the default impl is like the last choice, if no other impl matches...
Do you suggest that the default foo function can't actually "see" what the Ty is, even I write default type Ty = ();?
A default item is explicitly opting in to potentially not being the last choice.
The generic impl still has to be valid in that case, even though your code currently doesn't have any impls that are only overriding one of the trait items
Your generic impl requires the following impl to be allowed
impl Foo for String {
type Ty = String;
}
Since default items can be specialized separately. This impl doesn't make sense with the default fn your generic impl provides. That's why the generic impl is being rejected.
I never know I can partially implement a trait in specialization feature , and it looks that my guessing that the default foo function can't actually "see" what the Ty is right, they are totally unrelated?