As I said earlier, I would be against that. I'd rather get a panic from an off-by-one error than mysteriously get something from the back of the array instead. (It also means extra branching in indexing, and I wouldn't want a folk wisdom of "you shouldn't use signed numbers because they're slower" to develop if we did end up allowing signed numbers.)
Now, I wouldn't be against such a thing as a non-default option: v[std::cmp::Reverse(i)]
or v.rev()[i]
or v.cycle()[i]
or v[std::num::Wrapping(i)]
or something don't seem implausible. (I'm not making a proposal for any of those in core right now, though -- I haven't thought through whether they're actually good ways of representing the idea.)
Because of LLVM GEP
restrictions, there doesn't need to be one. The implementation can just sext
to the larger of iN
and isize
, then bitcast to the unsigned version and call that. (Both of those operations being essentially free on modern CPUs even if LLVM doesn't optimize them away.)
I think that whenever you're applying a signed offset to an index, it'll be way easier to stay in signed and let .get(i+d)
return None
when you go off either end. isize
and usize
can both represent all legal indexes into non-ZSTs (again because of LLVM GEP
restrictions), and correctly checking all overflows when adding an isize
offset to a usize
base index to produce a unsize
index is quite a complicated thing to do.