Rust's slices (the most obvious thing you would index) have three ways to index them, if you are out of bounds the consequences are Undefined Behaviour; panic; and return None. Today those are provided by get_unchecked(), the Index operator and get() respectively. [[ Calling get_unchecked() is unsafe of course, but it's potentially faster because it has no bounds check ]]
I'm confident we sometimes want each of the three options, so if we're having the Index operator return None then get() presumably panics, or at least some new function is provided with that behaviour.
I reckon this just drives annoyance that [k] has to be unwrapped, while get(k) does what people actually wanted [k] to do. I could be wrong, but that's my sense.
I don't think I agree that we need three different things to handle them. We already have a general mechanism to convert an Option<T> to a T and panic on None, a method which shall not be named. So we just need get and get_unchecked, really.
If the index operator is offered as sugar over one of the basic operations, great. But why add sugar for a method call that we actually don't ever want to see in production code?
Since indexing is nearly always fallible, it should be fallible!