1

I have a trait MyTrait with a few structs that implement it. I have a fair amount of these structs in my application and I want to gather some statistics about them and aggregate. I decided to do this in a hashmap, something like HashMap<Rc<dyn MyTrait>, AggregatedStats>, where I can quickly index by a struct instance to get the aggregated data for it.

I'm new to Rust and having trouble figuring this out. Implementing PartialEq and Eq was simple enough, but I don't know what to do about Hash. Once I add it to MyTrait, it becomes unboxable (I get error E0038). Here is an example to recreate the issue:

use std::collections::HashMap;
use std::hash::Hash;
use std::rc::Rc;
use std::cmp;

trait MyTrait: Hash {
}

struct MyTraitKey {
    val: Rc<dyn MyTrait>
}

// dummy implementations of PartialEq and Eq
impl cmp::PartialEq for MyTraitKey {
    fn eq(&self, other: &Self) -> bool {
        true
    }
}

impl cmp::Eq for MyTraitKey {}

#[derive(PartialEq, Eq, Hash, Debug)]
struct Type1;
impl MyTrait for Type1 {}

#[derive(PartialEq, Eq, Hash, Debug)]
struct Type2(u8);
impl MyTrait for Type2 {}

fn main() {
    let mut container: HashMap<MyTraitKey,i32> = HashMap::new();
    container.insert(MyTraitKey {val: Rc::new(Type1 {})}, 3);
}

The error appears in the definition of val: Rc<dyn MyTrait>:

error[E0038]: the trait `MyTrait` cannot be made into an object

What can I do in this case?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
devil0150
  • 1,350
  • 3
  • 13
  • 36

0 Answers0