Besides, the slice API is full of "infallible" functions that panic when given bad parameters - just search for "Panics" in https://doc.rust-lang.org/stable/std/primitive.slice.html - because it's expected that it would be more annoying for people to deal with the fallibility (like having to manually `.expect()` or bubble up the error) when they "know" that it wouldn't fail.
(I happen to think Rust can and ought to substantially improve the ergonomics of infallible API design, as well as provide more compiler support for avoiding fallible dependencies. But it's unreasonable to treat fallibility as a deficit, since it's explicitly outside of Rust's safety model.)
(I think we're in agreement about fallible APIs being confusing and a footgun.)
https://doc.rust-lang.org/core/convert/enum.Infallible.html
Infallible is the type of errors which can't happen. It will some day be a synonym for ! (aka Never, the type of return and break and such things) but even today it's an Empty Type.
Empty Types are in some sense even smaller than the Zero Size Types like the empty tuple. The ZSTs have a value, it's just always the same value and so it needn't be stored anywhere. The Empty Types don't even have a value. So not only do you not need anywhere to store their value, you don't even emit code to handle this value. Generic error handling code evaporates at compile time for Infallible.
The other kind of infallibility is "the absence of an error encoding for a function means the function cannot fail". The Infallible type can't provide that, since a function have an infallible `Err` case but still arbitrarily decide to panic at runtime.
Edit: in other words, Rust's type system isn't strong enough to encode "full" infallibility. We'd need some kind of effect typing for that.
True. I think it would've been nicer to make it return an Option type, but I guess performance would suffer if they made everything consistent.
As I said in the original comment, the reason these functions panic is that the common case for them is where the caller is using parameters that ought to be valid already (either hard-coded or already checked). So it would be less ergonomic to require the callers to handle an error that they know won't happen.
https://godbolt.org/z/cfr8MEG6j https://godbolt.org/z/7crr4n66Y
I suppose I'm used to C/C++ compilers not going as far down the optimization rabbit hole as Rust seems to, where they often miss more complex optimizations like this in sufficiently advanced wrapper types etc.