This works, but just for slicing (and looks quite wacky to me). Range is a structure by itself, which can be used outside of slicing too, and can be used to store, well, a range, instead of defining separate start and len/end fields.
If there was impl BitAnd<RangeTo> for RangeFrom with Output=Range that returned the intersection (semantically very close to and logic) then you could do from.. & ..to
Extended to the rest of the Range types, the intersection operator could be useful for treating Ranges as general interval types.
Then the question is whether BitOr should be overloaded to mean union, but a union of 2 continuous intervals is not necessarily a continuous interval (representable by Range) so maybe not because it doesn't seem obvious what to return there.
It's maybe less a footgun in Rust due to strong integer typing; you know when it's a usize vs a isize. On the other hand, you may want a isize but forget to cast and have usize overflow auto-wrapping, so you enter another category of error prone. Anyway, I agree with you.
It's a bit annoying that sometime, you need [..s.len() - 1] but you already have a mutable reference on s so you need to extract s.len() in a variable, but that's rare enough to make with it.
I think that this would be a useful feature. My code has several examples of converting a start and length to Range to pass it elsewhere. (Many of them are start..start + 1 to specify a single element.)
However, the computation can have a numeric overflow, if start + length overflows. The appropriate behavior would need to be considered in the design of this function. Since data[start..][..length] reliably panics if the length is too large, it might be appropriate for Range::from_len(start, length) to panic too, even if overflow-checks are disabled.
This means that your point "Doesn't have a possibility to express an invalid (start > end) range" doesn’t quite hold: on overflow, it will have to deal with that invalid input.
Also, @appleGun22, since you’re new here, note that in order to add Range::from_len(), you don't necessarily have to convince the audience here on internals.rust-lang.org; you only need to convince the standard library team, which takes API Change Proposals. In order to write a successful ACP you would need to flesh out your proposal a bit more, particularly with real-world examples of code it would improve, and the feedback here may help you prepare.
The proposed ..+ syntax avoids the ambiguity with unary + in Rust, since it doesn't have such, nor can an number literals start with a +. However it's still ambiguous with a.. + b.
Without saying whether such an operator is a good idea, it would be a straight-forward edition change to have ..+ become an operator and just insist that all existing ..+ be changed to .. +. (Especially since I doubt there's any non-contrived ..+ in the wild.)
I think this is impossible, since indexing operator can only return values in places that already exist, given the signature
fn index(&self, index: Idx) -> &Self::Output;
(note the connected lifetime of &Self::Output to &self from elision)
and (start..)[..count] would then desugar to *Index::index(&(start..), ..count)). But start.. of course does not happen to already contain the result of calculating start..start+count (for every possible value of count) inside of it
a.. + bdoesn’t actually parse successfully, since + has higher precedence than .. - so the only place this sequence of tokens can currently come up is in macros that never end up parsing them as an expression at all.