On Tuesday, 3 October 2023 at 17:05:46 UTC, Steven Schveighoffer
wrote:
```d
void main()
{
S s = 0;
{
scope int[] __r3 = s.opIndex()[];
ulong __key4 = 0LU;
for (; __key4 < __r3.length; __key4 += 1LU)
{
int x = __r3[__key4];
}
}
return 0;
}
```
Note the difference in how the foreach code is lowered. Inside
`opIndex`, it's lowered to the range functions. Outside, it
uses the slice operator to switch to iterating a `scope int[]`.
Naturally, this lowering is completely absent from [the language
spec's section on `foreach`.][1] According to the spec, the only
ways to iterate over a `struct` type are `opApply` and the input
range interface.
I think it would probably be less confusing to have both
`opApply` and `empty`/`front`/`popFront` take precedence over
this lowering, but I have no idea how much existing code would be
broken by such a change. At the very least, though, this needs to
be documented.
[1]: https://dlang.org/spec/statement.html#foreach-statement