Bug 24634 – Parse error initializing array from expression with StructInitializer

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2024-06-26T22:30:43Z
Last change time
2024-06-29T15:32:25Z
Keywords
pull
Assigned to
No Owner
Creator
Tom Kral

Comments

Comment #0 by mail — 2024-06-26T22:30:43Z
Compiling the following code fails with: Error: found `}` when expecting `;` following expression ``` struct A { int val; } enum A[2] as = [{0}, {1}].update; auto update(A[] as) { foreach (ref a; as) a.val++; return as; } ``` Interestingly, if I replace struct initializers with struct ctors, e.g.: ``` enum A[2] as = [A(0), A(1)].update; ``` the code compiles just fine.
Comment #1 by b2.temp — 2024-06-27T12:33:36Z
That's not really a bug. The problem is that StructInitializer is not supported when the variable initializer is an AssignExpression. You can verify that in the specifications: https://dlang.org/spec/declaration.html#initialization: ``` auto A[1] as = [{0}]; ``` takes the path of ArrayLiteral. ArrayLiteral supports StructInitializer. ``` auto A[1] as = [{0}].update(); ``` takes the path of AssignExpression. AssignExpression dont support StructInitializer. As a workaround you can decompose ``` auto A[1] as0 = [{0}]; auto A[1] as1 = [{0}].update(); ```
Comment #2 by b2.temp — 2024-06-27T12:34:28Z
Sorry I meant to write ``` auto A[1] as0 = [{0}]; auto A[1] as1 = as0.update(); ```
Comment #3 by nick — 2024-06-27T13:26:44Z
> AssignExpression dont support StructInitializer No - AssignExpression can be a PostfixExpression, which can have a PrimaryExpression on the left, which can be an ArrayLiteral, which can have a StructInitializer element.
Comment #4 by mail — 2024-06-27T17:36:00Z
(In reply to basile-z from comment #2) > Sorry I meant to write > > ``` > auto A[1] as0 = [{0}]; > auto A[1] as1 = as0.update(); > ``` Hmm, I find it rather surprising that StructInitializer would not work in this case. Is there a good reason for that? Thanks for the workaround by the way, it did the trick.
Comment #5 by dlang-bot — 2024-06-29T09:55:53Z
@ntrel created dlang/dlang.org pull request #3864 "[spec] Restore *ArrayInitializer*" fixing this issue: - [spec] Restore *ArrayInitializer* It was merged with ArrayLiteral in #3215 (oops). Fixes Bugzilla 24634 - Parse error initializing array from expression with StructInitializer. Add examples. https://github.com/dlang/dlang.org/pull/3864
Comment #6 by nick — 2024-06-29T10:01:39Z
basile-z is right that the compiler can't parse a struct initializer as part of an expression. The ArrayLiteral spec was wrong - the pull fixes that. Tom Kral: > I find it rather surprising that StructInitializer would not work in this case. Is there a good reason for that? It is part of a function argument, which in turn is part of an expression initializer (because a function call is an expression). An expression cannot parse all initializers because some initializers (e.g. `{}` for struct) mean something else as an expression (a function literal). So initializers are not accepted inside an expression.
Comment #7 by dlang-bot — 2024-06-29T15:32:25Z
dlang/dlang.org pull request #3864 "[spec] Restore *ArrayInitializer*" was merged into master: - 4700925acae3df03c6e5399f81df47927240be6a by Nick Treleaven: [spec] Restore *ArrayInitializer* It was merged with ArrayLiteral in #3215 (oops). Fixes Bugzilla 24634 - Parse error initializing array from expression with StructInitializer. Add examples. https://github.com/dlang/dlang.org/pull/3864