Clarification over benefits of associated types

In the associated types RFC it states that currently this is impossible because Rust doesn't distinguish between Input and Output types. Associated types are then suggested as the solution because they are an output type.

// This isn't supposed to work because of
// conflicting implementations.
impl Add<int, int> for int { ... }
impl Add<Complex, Complex> for int { ... }

My question is why does it work now without associated types? If it works without associated types then the benefit of that RFC seems much less than when it was originally written.

If the benefits that associated types brings have changed since that RFC, what are they now?

2 Likes

cc @huon @aturon Trying to get a pro in here who knows the answer. I've got a PR for rustbyexample which is blocked on this question. Though, you might be too busy to answer ...

Hmm. Is this because of the "multidispatch" portion of the RFC? See the section titled "The input/output type distinction". There's an example:

// These impls have distinct input types, so are allowed
impl Iterable1<u8> for Foo { ... }
impl Iterable1<char> for Foo { ... }

And this part:

More formally, the coherence property is revised as follows:

  • Given a trait and values for all its type parameters (inputs, including Self), there is at most one applicable impl.

Linking for easier finding: input/output type distinction section. I'll look into it.

Thanks for that. It was very helpful.

It seems the problem is that the statement at the beginning of the RFC is vague about why it used to not work in the past but it does state that input parameters are now being used to specify impl.

So, in addition to parameters now being labeled as input and associated types as output, impl parameters are now fully examined for uniqueness. This is why it now works.

Still, the motivating examples actually didn't need associated types...by design. Odd.

The associated types RFC introduced the distinction between input and output types. That means that, in particular, type parameters are treated as inputs, which means that each distinct set of type parameters is effectively a distinct trait (can be implemented separately, etc).

Put differently, the RFC didn't just add associated types, it also changed the way that trait type parameters work, precisely to allow this kind of example.

Okay. I think that makes sense but it wasn't clear from the Summary or Motivation that type parameter behaviour was changing. Just that output types were being added to compliment the already present input type.

Maybe that's what this was supposed to mean:

This RFC also provides a mechanism for multidispatch traits, where the impl
is selected based on multiple types. The connection to associated items will
become clear in the detailed text below.

But either way it wasn't clear to me.

Thank you for clarifying.