Specialization on output associated type

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:

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 } 

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?

May be it’s worth to read book articles? Look rust by example?

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.


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