According to the docs (https://dlang.org/spec/operatoroverloading.html#slice_assignment_operator), this should work as:
> Expressions of the form a[i..j] = c are rewritten as a.opIndexAssign(c, a.opSlice(i, j)), and a[] = c as a.opIndexAssign(c).
---
struct Foo
{
int payload;
auto ref opSlice(size_t start, size_t end)
{
return this;
}
auto opIndexAssign(T)(T elem, Foo foo)
{
pragma(msg, "opIndexAssign");
return this;
}
}
void main(string[] args)
{
Foo foo;
pragma(msg, typeof(foo[0..2]));
foo[0..2] = 3;
}
---
However, it fails with
> test.d(20): Error: cannot implicitly convert expression 3 of type int to Foo
AFAICT there's no reason why this lowering should fail (and at the very least, the error message needs to be improved).
As a workaround the legacy opSliceAssign can be used and looking at Phobos only opSliceAssign is used and there's no use of this specific newer opIndexAssign lowering.
Comment #1 by ogion.art — 2021-07-17T18:36:24Z
Works if opSlice is implemented as a template:
auto ref opSlice(size_t dim)(size_t start, size_t end) if (dim == 0)
According to reference, it should work as it is:
> If only one-dimensional slicing is desired, opSlice may be declared without the compile-time parameter.
Comment #2 by robert.schadek — 2024-12-13T18:59:11Z