On Monday, 18 October 2021 at 03:42:35 UTC, Paul Backus wrote:
What happens here is, the compiler first tries the D2-style rewrite:

```d
s.opIndexAssign(arr[1..4], s.opSlice!0(0, 3))
```

However, that rewrite fails to compile, because your `opSlice` does not take a template argument specifying the dimension along which to slice, as specified in the language spec's section on ["Slice Operator Overloading".][1]

Since the above rewrite fails to compile, it falls back to rewriting the expression using D1-style operator overloads:

For backward compatibility, `a[]` and `a[i..j]` can also be overloaded by implementing `opSlice()` with no arguments and `opSlice(i, j)` with two arguments, respectively. This only applies for one-dimensional slicing, and dates from when D did not have full support for multidimensional arrays. This usage of opSlice is discouraged.

...which results in the following rewritten statement:

```d
s.opSlice(0, 3) = arr[1..4];
```

My guess is that you got into this situation by trying to follow the example in the spec's section on ["Slice Assignment Operator Overloading"][2]. Unfortunately, that example is incorrect.

Here is a fixed version of your example on run.dlang.io: https://run.dlang.io/is/dtfT5y

[1]: https://dlang.org/spec/operatoroverloading.html#slice
[2]: https://dlang.org/spec/operatoroverloading.html#slice_assignment_operator

Woow! You fixed the problem, it now works for me.

I wish the compiler would have been able to make me understand the problem. It was no help because it only tells the final erroneous consequence, that the return value of `opSlice` cannot be assigned ("is no lvalue", beginner-unfriendly language). It doesn't even mention `opSlice` or the fallback (reason) with no warning.

Reply via email to