Specialization on output associated type


#1

Hello all!

I’m struggling with the specialization. The final goal is to make a bunch of types which can be transformed into each other, depending on the combinations, with compile-time checking. A very simplified example is the following:

#![feature(specialization)]
use std::marker::PhantomData;

trait A {
    type Out;
    fn f(&self) -> Self::Out;
}

struct S<T> {
    data: PhantomData<T>
}

impl<T> A for S<T> {
    default type Out = i32;
    default fn f(&self) -> Self::Out { 0i32 }
}

impl A for S<i64> {
    type Out = f64;
    fn f(&self) -> Self::Out { 1.0f64 } 
}

playground
This code throws an error, because I can’t return prescribed type as associated default, since it can be overwritten in other implementations:

error[E0308]: mismatched types
  --> src/lib.rs:15:40
   |
15 |     default fn f(&self) -> Self::Out { 0i32 }
   |                            ---------   ^^^^ expected associated type, found i32
   |                            |
   |                            expected `<S<T> as A>::Out` because of return type
   |
   = note: expected type `<S<T> as A>::Out`
              found type `i32`

But what if I should force the f() method to always return associated type, no matter how it is overwritten? Is it possible at current stage?


#2

May be it’s worth to read book articles? Look rust by example?
https://doc.rust-lang.org/book/2018-edition/ch19-03-advanced-traits.html


#3

Associated types are an especially thorny issue in specialization. The compiler is correct, your default for f is not admissible, because it does not cover all possible types that type Out can have. In other words, it has to be generic in some way, or not given as a default at all.

What you are after, to require both Out and f to be specialized together, cannot be expressed like this at the moment.

Also, specialization has been unstable for a long time, and the outlook for this feature is unclear. I would avoid especially relying on specialization of associated types. Best to find another way, and maybe avoid specialization all together.


#4

I see, thanks. I’ll try to find another way around then.