As part of brainstorming 2019 priorities, one of the things I’ve been contemplating is “when do people pick homogeneous tuples (or tuple-structs) instead of arrays?” We’re actually getting to a pretty good spot there, especially since fixed-length slice patterns stabilized in 1.26.
The big difference that still exists is that the compiler understand disjoint borrows for tuples/structs, so
foo(&mut x.0, &mut x.1) works when
foo(&mut x, &mut x) doesn’t. I think that the latter not working is pretty much fine – going through
IndexMut and taking runtime values and such means it not working is arguably actually a good thing.
The idea: what if we let the former just work for arrays?
- It’s not ambiguous, since arrays don’t have fields.
- It’s clear that it doesn’t support runtime indexes
- It thus wouldn’t compile if you look at an index that doesn’t exist
- It’s the same syntax as for tuples|structs where the compiler understands disjoint borrows
- It wouldn’t allow simultaneous
&mut xexactly the same as if you implement
IndexMuton a tuple struct (since the latter is a borrow of the whole object, not just a field).
- It’s hopefully easy in borrowck, since it’s the same logic as if
[T; N]were sugar for using a
#[repr(linear)] struct ArrayN<T>(T, T, ..., T);
Edit after some discussion on discord:
- I actually prefer the
.0form to making
xwork somehow (for const expressions or literals or something), since I like the syntactic difference. I don’t want people writing something with constants first, then having the code break when they move it to using a variable. (That goes in the same category for me as the fact that
if falseisn’t treated as unreachable, and that
.fieldworks differently from
I don’t know if this should be allowed on slices.Good point, @Yato: Allowing this on slices would mean that “field access” would throw, breaking the parallels this is trying to set up, so this shouldn’t be allowed on slices.