Lets discuss Inhabited trait

Because uninitialized and zeroed are not only ways to create uninhabited type values, e.g. you can write:

let a: Void = unsafe { mem::transmute(ZstType) };

And I think there is other holes like that, which I can’t recall now. So shouldn’t we simply place Inhabited trait bounds on function and let type system handle it from here? And in some cases you may want to use !Inhabitted trait bound, as in marker types, or if we’ll take Result:

// Inhabited bound is redundant, I'll use it for explicitness
impl<T: Inhabited, E: !Inhabited> Result<T, E> {
    /// Safely unwraps Ok variant
    fn always_ok(self) -> T {
        // I think it will not work today, but in future compiler may
        // prove that Result<T, !> is equivalent to T
        unsafe { mem::transmute(self) }
    }
}

impl<T: !Inhabited, E: Inhabited> Result<T, E> {
    fn always_err(self) -> E { .. }
}

One of the arguments which I’ve heard against Inhabited trait bound is that it will make things like Box<[!]> to require explicit ?Inhabited bounds, which can infect a lot of code bases. But I haven’t heard an explanation why we need such strange types in the first place.