Bug 19900 – Rewrites for unary index operator not done per the spec

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-05-24T15:28:45Z
Last change time
2024-12-13T19:03:32Z
Assigned to
No Owner
Creator
Bolpat
Moved to GitHub: dmd#19570 →

Comments

Comment #0 by qs.il.paperinik — 2019-05-24T15:28:45Z
The rewrites for unary operator before a slice expression reject valid code. Only the part tagged with "For backward compatibility" properly compiles. struct S { static struct Slice { size_t l, u; } Slice opSlice(size_t l, size_t u) { return Slice(l, u); } S opIndexUnary(string op)(Slice slice) { return S.init; } } unittest { S a; S b = ++a[1 .. 2]; // fails S c = a.opIndexUnary!("++")(a.opSlice(i, j)); }
Comment #1 by qs.il.paperinik — 2019-05-27T00:51:31Z
Some tests [1] show that in the rewrites of opSlice sometimes require a template parameter for the dimension to be performed by the compiler. The cases I found in [1] are opIndexUnary, opIndexOpAssgin, and opIndex. The rewrite for opIndexAssign, for some reason, is unaffected. [1]: struct TestStruct(bool opSliceWithDim, bool opDollarWithDim) { static if (opSliceWithDim) { size_t[2] opSlice(size_t dim)(size_t l, size_t u) { return [ l, u ]; } } else { size_t[2] opSlice(size_t l, size_t u) { return [ l, u ]; } } static if (opDollarWithDim) { enum size_t opDollar(size_t dim) = dim; } else { enum size_t opDollar = 1; } void opIndexUnary(string op)() { } void opIndexUnary(string op)(size_t index) { } void opIndexUnary(string op)(size_t[2] slice) { } void opIndexAssign(int rhs) { } void opIndexAssign(int rhs, size_t index) { } void opIndexAssign(int rhs, size_t[2] slice) { } void opIndexOpAssign(string op)(int rhs) { } void opIndexOpAssign(string op)(int rhs, size_t index) { } void opIndexOpAssign(string op)(int rhs, size_t[2] slice) { } int opIndex() { return 0; } int opIndex(size_t index) { return 0; } int opIndex(size_t[2] slice) { return 0; } } static foreach (enum bool opSliceWithDim; [ false, true ]) static foreach (enum bool opDollarWithDim; [ false, true ]) { unittest { alias S = TestStruct!(opSliceWithDim, opDollarWithDim); S s = S.init; int value = 0; s[] = value; // same as s.opIndexAssgin(value); s[1] = value; // same as s.opIndexAssgin(value, 1); s[3 .. $] = value; // same as s.opIndexAssign(value, s.opSlice(3, s.opDollar)) s[] += value; // same as s.opIndexOpAssgin!"+"(value); s[1] += value; // same as s.opIndexOpAssgin!"+"(value, 1); static assert(opSliceWithDim == __traits(compiles, { s[3 .. $] += value; // same as s.opIndexOpAssgin!"+"(value, s.opSlice(3, s.opDollar)); })); ++s[]; // same as s.opIndexUnary!"++"(); ++s[1]; // same as s.opIndexUnary!"++"(1); static assert(opSliceWithDim == __traits(compiles, { ++s[3 .. $]; // same as opIndexUnary!"+"(s.opSlice(3, s.opDollar)); })); value = s[]; value = s[1]; static assert(opSliceWithDim == __traits(compiles, { value = s[3 .. $]; // same as s.opIndex(s.opSlice(3, s.opDollar)); })); } }
Comment #2 by robert.schadek — 2024-12-13T19:03:32Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19570 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB