D supports something along these lines.
Originally, it had magic support for the length identifier. If used within an index or slice expression, it would read the length property of the array. Later, the $ “operator” was introduced, which actually invoked the opLength method on the thing being sliced. So a[0..$] was rewritten to a[0..a.opLength()].
I feel like the Rustiest solution would be (all names bikesheddable) to first introduce a trait for accessing a thing’s length:
trait L: ?Sized {
type A;
fn len(&self) -> A;
}
impl<T> L for [T] {
type A = usize;
fn len(&self) -> usize { self.len }
}
// ...
Next, introduce a length “operator”. Let’s just use $ for now (although I think # is a slightly nicer choice). Define it such that it walks up the expression tree to the first index expression, then is substituted with a call to L::len on the subject of said index expression.
The alternative to the above is to introduce, into the prelude, some kind of End marker object and define Index overloads that work with that. But that seems like a fairly finicky solution which will require more code for users.