bool only has to be a lang item (so that e.g. if…else can know about it), but not necessarily a built-in type. (Alternately Result could be a lang item.) We could do all of this:
type bool = Result<(), ()>;
const false: bool = Err(());
const true: bool = Ok(());
type Option<T> = Result<T, ()>;
For None we would need generic constants:
const None<T>: Option<T> = Err(());
which is not too bad (we will probably grow generic constants at some point). But for Some, we would need some kind of value-parameterized constants:
const Some<T>(x: T): Option<T> = Ok(x);
which seems like a much bigger lift. Compile-time evaluable (C++ constexpr) functions wouldn’t be enough, because it also has to work in patterns.
If we had all of that, one thing I’m not totally sure of is whether everything would work out smoothly with respect to trait impls for these types.
(As an aside, this functionality corresponds to (a subset of) GHC’s recent PatternSynonyms language extension.)