error[E0392]: parameter `R` is never used
--> src/lib.rs:1:19
|
1 | pub struct Reader<R, T, F: FnOnce(R) -> T> {
| ^ unused parameter
|
= help: consider removing `R`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `R` to be a const parameter, use `const R: usize` instead
But using a marker such as PhantomData doesn't make sense, since the struct doesn't own R and T.
Also I don't want to use Box to avoid heap allocation.
Instead, remove the superfluous trait bound from the type:
pub struct Reader<F> {
f: F,
}
Only add back the parameters R and T on any impl block that actually requires them. You don't need the FnOnce bound for merely creating an instance of the struct, so you shouldn't add such an artificial restriction.
Incidentally, this is not a good reason to add PhantomData. Adding PhantomData<R> will mean that the compiler will behave as if the struct contained an R, which will affect variance and the implementation of auto traits such as Send and Sync. This will potentially lead to surprising errors due to an over-constrained implementation.
If anything, a PhantomData<fn() -> R> could be used, but here, even that isn't warranted.
One could argue you only need the bound at impl block, but adding R and T at type level has actual usage. Currently, a single type X could have multiple FnOnce implementation, without R and T at type level, you could run into multiple issue if you are implementing something over T.
I mean I did write PhantomData<fn(R) -> T> which has the correct variance. And your proposed PhantomData<fn() -> R> got the variance reversed.
error[E0207]: the type parameter `R` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:5:6
|
5 | impl<R, T, F: FnOnce(R) -> T> Reader<F> {
| ^ unconstrained type parameter
Sorry, I missed the exact type of the PhantomData. However, PhantomData<fn(R) -> T> is technically still too restrictive, because it determines variance even when F is not an Fn* type.