It is impossible to define a type like enum Void<T> {} because the type parameter is unused. Normally this can be solved by embedding PhantomData, but there is nowhere to do this in an empty enum.
A workaround is struct Void<T> { _foo: PhantomData<T>, _bar: InnerVoid } enum InnerVoid {} which preserves the opaqueness of the type and inability to construct it.
I wonder if it's worth special casing variance inference (which is why T needs to be used) for this case to be a specific variance.
Triage: no changes. Given that nobody has requested this since 2016, I think I'm gonna give it a close. Thanks!
@steveklabnik i just randomly stumbled across this issue 11 days after you closed it, because i have this exact problem.
this would actually be useful to me. specifically not requiring type parameters to be used in an empty enum would be cool for type-level magic.
Another workaround is to have an unreachable variant
use std::convert::Infallible;
use std::marker::PhantomData;
enum Foo<T> {
_Bar(Infallible, PhantomData<T>),
}
With exhaustive_patterns it gets treated like a true empty enum, allowing an empty match:
#![feature(exhaustive_patterns)]
fn foo<T>(foo: Foo<T>) -> T {
match foo {
}
}
It would be neat to have phantom data in an enum without needing an unreachable variant for it, though. Regardless of whether the enum is empty or not.
Most helpful comment
@steveklabnik i just randomly stumbled across this issue 11 days after you closed it, because i have this exact problem.
this would actually be useful to me. specifically not requiring type parameters to be used in an empty enum would be cool for type-level magic.