They would indeed become an obsolete pattern, but keeping the options open can still be useful: in the same vein that () does not make any zero-sized struct useless (even if we ignored new-type usage for traits) since they can convey richer information.
Take, for instance, the return type of ::std::iter::Iterator::next(), and let’s call it IteratorState<Item>:
-
Currently, IteratorState<Item> is Option<Item>:
type IteratorState<Item> = enum Option<Item>
{
Some(Item),
None,
}
-
with generators, it could be seen as ::std::ops::GeneratorState<Iterator::Item, ()>,
i.e.,
type IteratorState<Item> = enum GeneratorState<Item, ()>
{
Yielded(Item),
Complete(()),
}
And although the one-type-fits-them-all is elegant logical-patterns-wise, that Complete(()) does not look nice (although quite better than the initial None!). With an (isomorphic) custom type, we could improve it:
-
enum IteratorState<T>
{
Yielded(T),
Exhausted,
}
use self::IteratorState::*;
impl<T> IteratorState<T> {
fn some(self) -> Option<T> { match self {
Yielded(value) => Some(value),
Exhausted => None,
}}
}
I thus think that custom never types may very well exist, either in the form
struct Never /* = */ (!);
or in the empty enum form. Hence the need for such a trait.
As an aside, I find custom inhabited types useful for “type-level enums”, since it prevents using them as values.
Those are useful for truly immutable settings that can then lead to constant propagation and dead code removal:
trait Bool { const TRUTH: bool; fn is_true () -> bool { Self::TRUTH } }
enum True {} impl Bool for True { const TRUTH: bool = true ; }
enum False {} impl Bool for False { const TRUTH: bool = false; }
/// they can be "converted back to (zero-sized) values" with `PhantomData`
use ::std::marker::PhantomData;
struct Config<Verbose : Bool> {
// ...
_phantom: PhantomData<Verbose>,
}
impl<Verbose : Bool> Config<Verbose> {
fn run (
// ...
)
{
if Verbose::is_true() { /* be verbose */ }
// do some stuff
if Verbose::is_true() { /* be verbose */ }
// do more stuff
if Verbose::is_true() { /* be verbose */ }
}
}