Too many generic parameters

I faced this problem for too many times: I need a struct with a generic field that implements a generic trait, then it turns into something like this:

struct MyStruct<A, B, C, B0, B1, C0, C1>
where
  A: Foo<B, C>,
  B: Bar<B0, B1>,
  C: Baz<C0, C1>,
{
  field_name: MyType<A>,
}

This leads to a few problems:

  • It is hard to type, especially when implementing trait or write a function that involve this struct.
  • Order of generic parameters is confusing and hard to remember. Accidentally use the wrong order or forget some parameters would lead to confusing error messages.
  • It is easier to make a breaking change on accident.

Questions:

  1. Is there a way to simplify this?
  2. If you were to make a proposal to the language (internals.rust-lang.org), what would you propose?

Also, for reference, this is surprisingly simple in TypeScript:

interface MyStruct<T extends Foo<any, any>> {
  field_name: MyType<T>
}

Consider just not putting where bounds on the struct at all.

1 Like
  1. Your suggestion only works when MyType don't have bound.
  2. Your suggestion, if works, only solve struct declaration, not trait implementations and functions.

Your TS example seems closer to

struct MyStruct<T> where T: for<A, B> Foo<A, B> {
  field_name: MyType<T>,
}

which you can't actually write today (though there are other ways to write very similar in meaning things).

In the Rust code you gave the struct is being specialised to only a single implementation of Foo<B, C> for A and won't be able to call Foo<D, C> if that was also supported.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.