Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an elegant way to make a generic tuple struct with an unused type without PhantomData?

I'd like to create a generic tuple struct Producer which can hold any type P which implements the trait Produce<T>, defined below. This produces the (expected) commented error:

trait Produce<T> {
    fn get(&mut self) -> T;
}

// ERROR: parameter `T` is never used [E0392]
struct Producer<P,T>(P) where P: Produce<T>;

If this were a non-tuple struct, I could remedy this issue by adding a PhantomData<T> field and writing a constructor Producer::new(p: P) to hide this as an implementation detail. However, I'm using this type as one of a family of tuple structs in a Builder API, so using a conventional struct + constructor feels pretty out of place.

Is there any way to achieve this?

like image 864
zslayton Avatar asked Sep 25 '15 15:09

zslayton


1 Answers

In many cases, you don't want to parameterize your trait, but instead want an associated type:

trait Produce {
    type T;

    fn get(&mut self) -> Self::T;
}

struct Producer<P>(P) where P: Produce;

fn main() {}

Unfortunately, it's tough to tell if this will work for you without knowing a lot more about the anticipated use case and code examples, which might be too verbose for Stack Overflow.

like image 133
Shepmaster Avatar answered Dec 09 '22 10:12

Shepmaster