zslayton
zslayton

Reputation: 52825

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?

Upvotes: 9

Views: 5704

Answers (1)

Shepmaster
Shepmaster

Reputation: 430831

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.

Upvotes: 13

Related Questions