# Polymorphic "implements" clause on associated types

**URL:** <https://internals.rust-lang.org/t/polymorphic-implements-clause-on-associated-types/1636>\
**Category:** ideas (deprecated)\
**Created:** [February 23, 2015, 9:38am UTC](https://internals.rust-lang.org/t/polymorphic-implements-clause-on-associated-types/1636 "2015-02-23T09:38:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![knz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/knz/32/826_2.png) [@knz](https://internals.rust-lang.org/u/knz)\
**Post date:** [February 23, 2015, 9:38am UTC](https://internals.rust-lang.org/t/polymorphic-implements-clause-on-associated-types/1636/1 "2015-02-23T09:38:01Z")

</div>

In a nutshell, let’s say I have a `trait A<T> { ... }`; then another `trait B { type X; ... }`. How can I state that type `X` in `B` always implements `A` _for all T_?

Something like `trait B { type X : A<*>; ... }` but this is not valid code.

I believe we miss an existential quantifier in associated type definitions (and possibly other places).

Advice from IRC suggested definining `B` with a parameter, ie. `trait B<T> {type X : A<T>; ... }` however this does not work as soon as some other items in `B` wish to exploit the genericity of `X`; for example:

```
trait A<T> { type O; ... }
trait B<T> {
    type X : A<T>;
    fn transform<U>(x : U) -> <X as A<U>>::O;
    // ^^^^
    // Error: X does not implement A<U>, only A<T>
} 

```

Were it possible to write the generic form this error would evaporate:

```
indent preformatted text by 4 spaces
trait A<T> { type O; ... }
trait B {
    type X : A<*>;
    fn transform<U>(x : U) -> <X as A<U>>::O;
    // ^^^^ OK
} 

```

I first submitted this as [this issue on the bug tracker](https://github.com/rust-lang/rust/issues/22675), which in turn illustrates an attempt to shoe-horn a reduced yet powerful form of HKTs in the current associated type machinery, inspired from [this example](https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md%23encoding-higher-kinded-types) from last year.

However do not let this mention of HKTs distract from the present discussion: even if HKTs are to be implemented using a different approach, I believe that existential implementation specifiers such as proposed above would still be useful. **Meanwhile, if you are really interested in HKTs, notice that they would come for free as a by-product of the existential quantification described above.**

---

<div class="post-metadata">

**Author:** ![knz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/knz/32/826_2.png) [@knz](https://internals.rust-lang.org/u/knz)\
**Post date:** [February 23, 2015, 9:54am UTC](https://internals.rust-lang.org/t/polymorphic-implements-clause-on-associated-types/1636/2 "2015-02-23T09:54:38Z")

</div>

I just noticed the `for` keyword for existential quantifiers for _lifetimes_ (see [https://github.com/rust-lang/rfcs/pull/387](https://github.com/rust-lang/rfcs/pull/387)) so the example above really is a call to implement the last part of [https://github.com/nikomatsakis/rfcs/blob/hrtb/active/0000-higher-ranked-trait-bounds.md](https://github.com/nikomatsakis/rfcs/blob/hrtb/active/0000-higher-ranked-trait-bounds.md) which would enable the following solution:

```
trait A<T> { ... }
trait B { type X : for<T> A<T>; ... }
// ^^^ not currently valid, should perhaps become valid.
```

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [February 23, 2015, 3:51pm UTC](https://internals.rust-lang.org/t/polymorphic-implements-clause-on-associated-types/1636/3 "2015-02-23T15:51:41Z")

</div>

You can always write:

```rust
trait A<T> { type O; ...}
trait B<T> {
    type X : A<T>;
    fn transform<U>(x : U) -> <Self::X as A<U>>::O where Self::X: A<U>;
}

```

However, this obviously doesn’t guarantee that `B<T>` is implemented for all `T`. You could also blanket impl `B<T>` for all `T` but that also doesn’t let the user assume that `B<T>` is implemented for all `T`:

```rust
trait A<T> { type O; ... }
trait B<T> {
    type X : A<T>;
    fn transform(x : T) -> <Self::X as A<T>>::O;
}

impl<T> B<T> for ... {}

```

---

<div class="post-metadata">

**Author:** ![knz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/knz/32/826_2.png) [@knz](https://internals.rust-lang.org/u/knz)\
**Post date:** [February 23, 2015, 9:13pm UTC](https://internals.rust-lang.org/t/polymorphic-implements-clause-on-associated-types/1636/4 "2015-02-23T21:13:37Z")

</div>

I have tried to do this but I run into issues if I need to encapsulate anonymous closures, see [https://gist.github.com/knz/45a2987d1369dbdb0cc8](https://gist.github.com/knz/45a2987d1369dbdb0cc8) for details about the specific error. Unsure how to proceed.

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [February 23, 2015, 10:12pm UTC](https://internals.rust-lang.org/t/polymorphic-implements-clause-on-associated-types/1636/5 "2015-02-23T22:12:52Z")

</div>

Looking at the first error, it makes sense because

```
fn pr<A>(x : A) -> <Self as Tr<A>>::O where Self : Tr<A>;

```

is (obviously) conditional on `Self` implementing `Tr<[the argument type]>`; when called from `foo`, the argument type is a unique anonymous closure, while the bounds on `foo` have only guaranteed that it implements `Tr<A>` and `Tr<B>` for some A and B which are completely unknown, except for the fact that the function arguments match associated types on them.

In general, I don’t think it’s possible to have a generic function take a generic type as parameter and then specialize it with a type only known within that function (the closure type); someone could let me know if I’m wrong. You could solve this by implementing your closure manually, i.e. with a struct containing state and `Fn` implementation, allowing you to name the required `Fn` trait in the function bounds. Alternatively, you could just use boxed closures (which you are doing anyway when you cast `id` to `&Fn(B)->B`…).

And yeah, this is one reason HKTs would be nice.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:23am UTC](https://internals.rust-lang.org/t/polymorphic-implements-clause-on-associated-types/1636/6 "2019-03-25T08:23:58Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
