Bug 23620 – 'alias this' is not respected in static array length position

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-01-11T13:48:49Z
Last change time
2023-01-17T03:36:25Z
Keywords
pull, rejects-valid
Assigned to
No Owner
Creator
Max Samukha

Comments

Comment #0 by maxsamukha — 2023-01-11T13:48:49Z
struct Index { uint value; alias value this; } enum i = Index(); int[i] a; void main() { } Error: integer constant expression expected instead of `Index(0u)`
Comment #1 by dlang-bot — 2023-01-11T14:53:55Z
@SixthDot updated dlang/dmd pull request #14803 "fix issue 23620 - 'alias this' is not respected in static array lengt…" fixing this issue: - fix issue 23620 - 'alias this' is not respected in static array length position does the cast to size_t before calling toInteger(), which emitted the error https://github.com/dlang/dmd/pull/14803
Comment #2 by dlang-bot — 2023-01-12T13:30:41Z
dlang/dmd pull request #14803 "fix issue 23620 - 'alias this' is not respected in static array lengt…" was merged into stable: - 4ed4e2c0ff1f238a0d4cdbccc21ec3d50d8f2706 by Basile Burg: fix issue 23620 - 'alias this' is not respected in static array length position does the cast to size_t before calling toInteger(), which emitted the error https://github.com/dlang/dmd/pull/14803
Comment #3 by dlang-bot — 2023-01-14T10:18:44Z
dlang/dmd pull request #14813 "Merge Stable into master" was merged into master: - 1fe9ffb6722c902bf0a3fcd78cfb740bcbf1bc31 by Basile Burg: fix issue 23620 - 'alias this' is not respected in static array length position does the cast to size_t before calling toInteger(), which emitted the error https://github.com/dlang/dmd/pull/14813
Comment #4 by salihdb — 2023-01-14T21:03:06Z
This isn't a bug! void main() { struct Index { size_t value; alias value this; } enum size_t i = Index(); int[i] a;  int[cast(size_t)Index()] b;  static assert(a.length == b.length); }
Comment #5 by maxsamukha — 2023-01-15T05:12:23Z
Why? Explicit cast shouldn't be required.
Comment #6 by salihdb — 2023-01-15T07:02:08Z
// because : enum index1 = Index(); assert( is(typeof(index1) == struct) ); auto index2 = Index(); assert( !is(typeof(index1) == size_t) && !is(typeof(index2) == size_t) ); // but: enum index = Index(); int[index + 1] d; // automatic conversion d[0] = 42; // yeah SDB@79
Comment #7 by maxsamukha — 2023-01-15T07:50:52Z
(In reply to Salih Dincer from comment #6) > // because : > > enum index1 = Index(); > assert( > is(typeof(index1) == struct) > ); > > auto index2 = Index(); > assert( > !is(typeof(index1) == size_t) && > !is(typeof(index2) == size_t) > ); > > // but: > > enum index = Index(); > int[index + 1] d; // automatic conversion > d[0] = 42; // yeah > > SDB@79 I still don't understand. Static array declaration expects an integer. 'Index' implicitly converts to an integer. Why should casts or other hacks be required?
Comment #8 by salihdb — 2023-01-16T11:15:26Z
I don't understand too :) This code works me: struct Index(T) { T value; this(T v) { value = v; }; alias opCall this; @property opCall() inout { return value; } } enum one= Index!int(1)(); int[one] a = 1; int[Index!int(2)()] b = 2; static assert(a.length < b.length); Best regards... SDB@79
Comment #9 by maxsamukha — 2023-01-16T13:23:48Z
(In reply to Salih Dincer from comment #8) > I don't understand too :) > > This code works me: > > struct Index(T) > { > T value; > > this(T v) { value = v; }; > alias opCall this; > > @property opCall() inout { > return value; > } > > } > > enum one= Index!int(1)(); > int[one] a = 1; > > int[Index!int(2)()] b = 2; > static assert(a.length < b.length); > > Best regards... > > SDB@79 You don't need to mark opCall with @property for that code to work. 'alias this' is also unnecessary. You wrote "This isn't a bug!". Did you mean this bug report is invalid? If yes, it would be nice if you explained why you think the report is invalid.
Comment #10 by b2.temp — 2023-01-17T00:33:30Z
(In reply to Salih Dincer from comment #4) > This isn't a bug! > > void main() > { > struct Index > { > size_t value; > alias value this; > } > > enum size_t i = Index(); > int[i] a; >  int[cast(size_t)Index()] b; >  static assert(a.length == b.length); > } before the fix DMD did a hidden cast a cast but too late.
Comment #11 by salihdb — 2023-01-17T03:36:25Z
(In reply to Max Samukha from comment #9) > (In reply to Salih Dincer from comment #8) > > I don't understand too :) > > > > This code works me: > > > > struct Index(T) > > { > > T value; > > > > this(T v) { value = v; }; > > alias opCall this; > > > > @property opCall() inout { > > return value; > > } > > > > } > > > > enum one= Index!int(1)(); > > int[one] a = 1; > > > > int[Index!int(2)()] b = 2; > > static assert(a.length < b.length); > > > > Best regards... > > > > SDB@79 > > You don't need to mark opCall with @property for that code to work. 'alias > this' is also unnecessary. > > You wrote "This isn't a bug!". Did you mean this bug report is invalid? If > yes, it would be nice if you explained why you think the report is invalid. Here's how I think (please let's discuss privately via email or here): First you create an object and it is a struct. There is a strange working alias in the build. The related problem may be a bug for you. But is there any reason not neomorph it? Because CTFE is involved. But what if we don't want the object to occur where it occurs (in a variable without CTFE) that it points to, not itself? SDB@79