Making Rust core and alloc panic free

This will be quite speculative, but subtyping with pattern types could be useful for functions where the potential panics are due to required preconditions.

The simplest (and essentially useless) example of Option::unwrap could look like

// This would be the non-panicking signature for unwrap.
// In practice you'd want a way to merge it with the standard signature.
impl<T> Option<T> in Some(_) {
    fn unwrap(self) -> T {
        let Some(x) = self;
        x
    }
}

For indexing, with a bunch more imaginary syntax and associated handwaving, you might conceive something like:

impl<virtual N: usize, T> Index<usize in 0..N> for [T] in [_; N..] {
    fn index(&self, index: usize in 0..N) -> &Self::Output;
}

To be read as: For any virtual usize N, slices with at least N elements can be indexed with any usize less than N. By virtual I mean like const but may not monomorphize, so the body cannot depend on the value of N, which is only there to relate the types in the signature. Much like lifetimes.

For most general cases you'd still need to use alternatives like get, but at least this could cover some of the more obvious cases like indexing an array with some remainder of division by its constant length.

In a panic-free subset of Rust, you might then be able to use many APIs that would normally panic if some precondition is not met, as long as the inputs statically do meet them.

E.g.

#![deny(panic)]

let x: usize = ...
// ERR: usize / usize may panic
55 / x
// hint: usize / (usize in 1..) is panic-free, consider a match like:
match x {
    // OK because d has type usize in 1..
    d @ 1.. => 55 / d, 
    // OK because the literal 7 is not 0
    0 => 55 / 7, 
}