This code doesn't compile (playground):
struct Mapper<T, U, F>
where
F: Fn(T) -> U,
{
mapper: F,
// _t: PhantomData<T>,
// _u: PhantomData<U>,
}
impl<T, U, F> Mapper<T, U, F>
where
F: Fn(T) -> U,
{
fn new(mapper: F) -> Self {
Self {
mapper,
// _t: PhantomData,
// _u: PhantomData,
}
}
fn call(&self, t: T) -> U {
(self.mapper)(t)
}
}
The compiler says
error[E0392]: parameter `T` is never used
--> src/main.rs:3:15
|
3 | struct Mapper<T, U, F>
| ^ unused parameter
|
= help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `T` to be a const parameter, use `const T: usize` instead
error[E0392]: parameter `U` is never used
--> src/main.rs:3:18
|
3 | struct Mapper<T, U, F>
| ^ unused parameter
|
= help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `U` to be a const parameter, use `const U: usize` instead
However, this code compiles though I add PhantomData
only for T
:
use std::marker::PhantomData;
struct Mapper<T, U, F>
where
F: Fn(T) -> U,
{
mapper: F,
_t: PhantomData<T>,
// _u: PhantomData<U>,
}
impl<T, U, F> Mapper<T, U, F>
where
F: Fn(T) -> U,
{
fn new(mapper: F) -> Self {
Self {
mapper,
_t: PhantomData,
// _u: PhantomData,
}
}
fn call(&self, t: T) -> U {
(self.mapper)(t)
}
}
On the other hand, if I add PhantomData
only for U
, the code doesn't compile:
use std::marker::PhantomData;
struct Mapper<T, U, F>
where
F: Fn(T) -> U,
{
mapper: F,
// _t: PhantomData<T>,
_u: PhantomData<U>,
}
impl<T, U, F> Mapper<T, U, F>
where
F: Fn(T) -> U,
{
fn new(mapper: F) -> Self {
Self {
mapper,
// _t: PhantomData,
_u: PhantomData,
}
}
fn call(&self, t: T) -> U {
(self.mapper)(t)
}
}
fn main() {
let mapper = Mapper::new(|a: usize| -> isize { -(a as isize) });
println!("{}", mapper.call(3));
}
Why?