The struct you want to create is perfectly legal. Just delete the unused type parameters. If you have a reason for needing them, you should know what kind of PhantomData you want, and be glad the compiler allows you to specify it rather than assuming PhantomData<T> all the time.
But most of the time the correct solution is to delete the unused type parameters.
I was quite surprised that there are many ways PhantomData's "held" type(s) can be set up, and they each have different effects on drop checking, variance, and even whether a struct can be Sync or Send (see the docs).
Well, it's nothing special. Storing a PhantomData<T> means that your type will behave as if it contained an actual value of type T, except that it doesn't. Everything else follows from this.
When a struct has a type parameter, there are effects depending on how that type is used. This can affect variance and certain auto-trait implementations.
An example:
#![allow(dead_code)]
#![allow(unused_variables)]
use std::marker::PhantomData;
struct A<T> {
_phantom: PhantomData<T>,
}
struct B<T> {
_phantom: PhantomData<fn(T)>,
}
impl<T> A<T> {
fn new(arg: T) -> Self {
Self { _phantom: PhantomData }
}
}
impl<T> B<T> {
fn new(arg: T) -> Self {
Self { _phantom: PhantomData }
}
}
fn foo(arg: A<&'static String>) {}
fn bar(arg: B<&'static String>) {}
fn main() {
let s = "Hello".to_string();
let a = A::new(&s);
let b = B::new(&s);
//foo(a); // this will fail
bar(b);
}
There's no way to infer the variance of unused parameters. (Take care reading the RFC, as not all the ideas were implemented; there's no PhantomFn or other way to make trait parameters anything but invariant, etc.) Inserting PhantomData automatically would be akin to choosing a variance (et cetera). It could never get it always correct.
What are the parameters in your example used for? There may be another hacky way to work around it. You'd probably have to carry bounds around everywhere. This may not be as onerous as it sounds, since you probably already have to do that or to specify the types of the otherwise unused parameters everywhere already.