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