Rust says my generic parameter is not used

Relevant information

I have a trait BasisVector and a trait KVector<B> where B implements BasisVector.

struct MVector<V, B>
where
    V: KVector<B>,
    B: BasisVector,
{
    scalar: f32,
    basis: Vec<V>,
    coeffs: Vec<f32>,
}

I have a trait MVector<V, B> which I intend to implement for MVector:

trait MultiVector<V, B>: Signed
where
    B: BasisVector,
    V: KVector<B>,
{
    fn new(scalar: f32, basis: Vec<V>, coeffs: Vec<f32>) -> Self;
    fn scalar(&self) -> f32;
    fn basis(&self) -> Vec<V>;
    fn coeffs(&self) -> Vec<f32>;
}

However, the compiler says my struct is incorrect:

 1  error[E0392]: parameter `B` is never used
    --> src/main.rs:157:19
     |
 157 | struct MVector<V, B>
     |                   ^ unused parameter
     |
     = help: consider removing `B`, referring to it in a field, or using a marker such as `PhantomData`

Even though I use it in my where clause:

where
    V: KVector<B>,
    B: BasisVector,

Is there any way I can make this work without using Phantomdata?

1 Like

Your struct doesn't need to have any bounds. Remove them, and the unused B parameter. (You can still — and, regardless, must — place bounds on the struct's impl blocks.)

2 Likes

I'm confused, if I remove the generics the compiler will complain won't it?

Actually, I think I see what you mean, I can just remove the where clause? I'll try it now

Edit: Worked like a treat. I'll answer my own question how I understand it at least.

The key thing to note here is that there is no need for the where clause and by extension the generic parameter B as we need to specify here the shape of the struct.

Taking this into account the new struct looks like this:

struct MVector<V> {
    scalar: f32,
    basis: Vec<V>,
    coeffs: Vec<f32>
}

The trait implementation is where some of the data I was specifying can get specified:

impl<V, B> MultiVector<V, B> for MVector<V>
where
    B: BasisVector,
    V: KVector<B>,
{
   ...
}

The really important thing I and anyone else may take home with them is not to specify anything about your generics until it is absolutely necessary because doing so can lead to headaches.

Thank you to @kpreid for helping me out. Only reason that I didn't mark your answer as the solution is that it wasn't very obvious what exactly I had to do until I did it. Hope you understand :heart:.

This makes me want to rewrite my whole API again to be honest.

4 Likes