It does! But you still have to actually "use" it, meaning that it appears as a field in the definition, and you have pass a PhantomData value whenever you create new instances of your data type.
In Haskell, you can omit these fields entirely, and achieve the same thing just by annotating the function.
For example, in Haskell, we can have
data Const a b = Const a
whereas in Rust, it would be:
struct Const<A, B> {
konst: A,
// does not exist at run-time
discard: PhantomData<B>
}
Type parameter variance is inferred from usage (e.g. covariant for normal fields, contravariant for function arguments) and without a usage there's no way to infer it.
In Haskell, you can omit these fields entirely, and achieve the same thing just by annotating the function.
For example, in Haskell, we can have
whereas in Rust, it would be: