Error when not specifying associated type of a trait in function signature

I have this rust code

use std::collections::HashMap;

trait MyTrait{
    type mytype;
    fn foo();
    fn bar();
	fn baz(&self);
}

fn fun(arg: HashMap<String, Box<dyn MyTrait>>) {
    // process
}

fn main() {}

which gives me this error

error[E0191]: the value of the associated type `mytype` (from trait `MyTrait`) must be specified
  --> src/main.rs:10:37
   |
5  |     type mytype;
   |     ----------- `mytype` defined here
...
10 | fn fun(arg: HashMap<String, Box<dyn MyTrait>>) {
   |                                     ^^^^^^^ help: specify the associated type: `MyTrait<mytype = Type>`

I understand this error. But fun() can be called from multiple places with different possibilities of mytype I cannot bind mytype to a single type in fun() signature. what is the possible way to resolve this error

How about a generic parameter on fun instead, then?

use std::collections::HashMap;

trait MyTrait {
    type mytype;
    fn foo(&self);
    fn bar(&self);
    fn baz(&self);
}

fn fun<T>(arg: HashMap<String, Box<dyn MyTrait<mytype = T>>>) {
    // process
}

fn main() {}

Playground.

1 Like

When discussing the design of function signatures, it’s always important to also consider the call-site. Your example code does not show what the call-site of fun looks like. How is the HashMap constructed and what is the precise type of it?

If it is the case that your (as you described: multiple) call sites feature types such as HashMap<String, Box<dyn Trait<mytype = FooBar>> and HashMap<String, Box<dyn Trait<mytype = BazQux>>, then the approach @jofas suggested of making the function generic over the choice of that associated type, might be what you need, but that’s only based on my best guess of what your actual call-sites might possibly look like.

On the other hand, if you haven’t really tested the construction of the HashMap at all, it might also be the case that you’re trying to put different types with different associated type mytype definitions into one and the same HashMap, and in that case you would run into trouble before fn fun plays a role in the first place.

4 Likes

Since this approach creates multiple versions of fun() what if i don't want to opt for static binding like this? is there any other way

Hmm, right off the top of my head without knowing your setup I probably would suggest expanding your dynamic dispatch approach to mytype as well:

trait MyInnerTrait {}

trait MyTrait {
    type MyType;
    fn foo(&self);
    fn bar(&self);
    fn baz(&self);
}

fn fun(arg: HashMap<String, Box<dyn MyTrait<MyType = Box<dyn MyInnerTrait>>>>) {
    // process
}
1 Like

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.