1

I have a trait that looks like this:

pub trait Trait<K, V> 
{
    fn f<Q>(&self, k: &Q) -> Option<&V>
        where K: Borrow<Q>;
}

When I try to write a function

fn create<K, V>(params here) -> Box<dyn Trait<K, V>> {
...
}

That instantiates one of the objects that satisfies the trait depending on parameters, I get the following error:

the trait `Trait` cannot be made into an object
   |
   = note: method `f` has generic type parameters

I don't really understand why this is happening, or how to fix it.

Misguided
  • 1,302
  • 1
  • 14
  • 22
  • Does this answer your question? [Understanding Traits and Object Safety](https://stackoverflow.com/questions/44096235/understanding-traits-and-object-safety) – mcarton Dec 24 '19 at 20:23
  • See also https://stackoverflow.com/questions/38318497/what-safety-guarantees-of-rust-would-be-lost-if-not-for-object-safety – mcarton Dec 24 '19 at 20:25
  • Let me rephrase: I don't understand how to fix the issue. I still need the borrow on K, so it seems there's actually no way to implement this in Rust right now, correct? – Misguided Dec 24 '19 at 20:26
  • No. You are trying to mix generic methods, which are a static thing, with trait objects, which are dynamic. The simplest way to allow this would be to remove `Q` and accept `k: &K`. – mcarton Dec 24 '19 at 20:31
  • Reason is hidden in how trait obejcts work. You will always have a `vtable` for every implementation of a trait on an object. The `vtable` contains _concrete_ functions. That's to say, the types which go into each of the parameters is decided at compile time. Usually, generic functions are run through a process called monomorphization which will take generic functions and copy/paste them for each type they're used with. This will allow for type-specific optimizations. But then how would this work with trait objects? Should _every_ trait vtable implement every generic parameter ever used? – Optimistic Peach Dec 25 '19 at 06:07

0 Answers0