# Type parameter not used on enums

**URL:** <https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342>\
**Category:** traits working group\
**Created:** [November 6, 2020, 8:37pm UTC](https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342 "2020-11-06T20:37:39Z")\
**Posts on this page:** 6\
**Page:** 2

<div class="post-metadata">

**Author:** ![bill\_myers](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bill_myers/32/4085_2.png) [@bill\_myers](https://internals.rust-lang.org/u/bill_myers)\
**Post date:** [November 16, 2020, 7:11pm UTC](https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342/21 "2020-11-16T19:11:24Z")

</div>

You could also make R an associated type of Page instead of a generic parameter, if appropriate in your case.

---

<div class="post-metadata">

**Author:** ![mankinskin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mankinskin/32/6760_2.png) [@mankinskin](https://internals.rust-lang.org/u/mankinskin)\
**Post date:** [November 16, 2020, 7:18pm UTC](https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342/22 "2020-11-16T19:18:43Z")

</div>

Yes, I also considered that, but I want to have distinct `Page`s for different `R`s. If it was an associated type I could only have one `Page` implementation for each `MyPage`.

At this point it is not only about my specific case anymore, but about the general problem of parameterizing trait bounds in type definitions. I think there may always be legitimate reasons as to why you would want a construct like this:

```rust
enum MyEnum<R, P: Page<R>> {
    SetTitle(<P as Page<R>>::Title),
}

```

This is basically the need for higher order traits or [Kind](https://en.wikipedia.org/wiki/Kind_(type_theory))s, which still lacks support in the language.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [November 16, 2020, 9:46pm UTC](https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342/23 "2020-11-16T21:46:26Z")

</div>

> [@mankinskin](#):
>
> I think there may always be legitimate reasons as to why you would want a construct like this:

That's not obvious to me _on the `MyEnum` type itself_.

I totally agree that we want GATs and such, but it's not at all clear to me that it's valuable to tie that enum to those types just to get other types off them -- notably, the compiler has been making some changes in exactly the opposite direction recently. Monomorphizing a copy of `MyEnum` (and, more relevantly, it's methods) for every permutation of `P` and `R` is not great for code size and compilation time, especially if it's common for all those pages to use the same type for their title (as seems highly likely).

For the ergonomics part one could consider allowing `P::MyEnum` to be an associated type giving `MyEnum<P::Title>`, or something like that.

---

<div class="post-metadata">

**Author:** ![scalexm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scalexm/32/2402_2.png) [@scalexm](https://internals.rust-lang.org/u/scalexm)\
**Post date:** [November 17, 2020, 11:05am UTC](https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342/24 "2020-11-17T11:05:48Z")

</div>

The general rule of thumb is to use the smallest set of bounds necessary to correctly _define_ your type, not use it.

In your initial case, as others stated, this would look like:

```rust
enum Msg<P: Component> {
    Page(<P a Component>::Msg),
    UrlChanged(subs::UrlChanged),
}

```

If you need to add your `SetTitle` variant, then it’s fine to change the bound:

```rust
enum Msg<R, P: Page<R>> {
    ...
    SetTitle(<P as Page<R>>::Title),
}

```

and you’ll note that this compiles fine and does not exhibit a « parameter is never used » error.

Then, on _individual methods_, you add all the bounds you need for your implementation.

There are multiple advantages to this rule of thumb:

- you can fine tune bounds for specific use cases, for example `Hash + Eq` is needed in the general `HashMap` API, but not in the (nightly) `raw_entry` API
- you don’t need to carry your bounds everywhere even when you don’t need them (although this may be relaxed with implied bounds, as @scottmcm noted)
- you can add new behaviors with more constrained bounds without breaking code
- you’re almost always sure not to hit the « parameter is never used » error

---

<div class="post-metadata">

**Author:** ![mankinskin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mankinskin/32/6760_2.png) [@mankinskin](https://internals.rust-lang.org/u/mankinskin)\
**Post date:** [November 18, 2020, 5:18pm UTC](https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342/25 "2020-11-18T17:18:19Z")

</div>

> [@scalexm](#):
>
> you’ll note that this compiles fine and does not exhibit a « parameter is never used » error

Oh that is right. Neat. Is that because `R` now is used in the enums memory layout definition?

So the only limitation is that I can not constrain Rust types based on type parameters that do not constrain the memory layout..? That certainly makes sense from a memory perspective. From an abstract perspective I wish I didn't have such a limitation and could just tell the compiler to put those constraints on that type in any case. You could have much more expressive type models. But I can also see how this abstraction could end up as confusing and it would make it a lot easier to increase code size and compilation time. So I guess the existing methods are already pretty good.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [December 22, 2024, 4:55pm UTC](https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342/26 "2024-12-22T16:55:10Z")

</div>

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

[Previous page](https://internals.rust-lang.org/t/type-parameter-not-used-on-enums/13342.md?page=1)
