Issue 24763 - Can't use struct initializer in an array literal
Summary: Can't use struct initializer in an array literal
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 All
: P1 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-09-12 12:18 UTC by ryuukk_
Modified: 2024-09-13 09:35 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description ryuukk_ 2024-09-12 12:18:16 UTC
```D
struct Test
{
    int test;
}

struct Data
{
    Test[8] test;
}

void add(Data data)
{
}

extern(C) void main()
{
    add( Data(test: [ {test: 1}] ) );
}

```

This doesn't compile, it should
Comment 1 RazvanN 2024-09-12 12:49:57 UTC
A reduction of the test case:

struct Test
{
    int test;
}
  
void func(Test t) {}
  
void main()
{
  
    Test a = {test: 1}; 
    func({test: 1});                                                                                                                                                                                             
}

It seems that struct initializers only work when they are the rhs of an assign expression.
Comment 2 RazvanN 2024-09-12 13:06:52 UTC
(In reply to RazvanN from comment #1)
> A reduction of the test case:
> 
> struct Test
> {
>     int test;
> }
>   
> void func(Test t) {}
>   
> void main()
> {
>   
>     Test a = {test: 1}; 
>     func({test: 1});                                                        
> 
> }
> 
> It seems that struct initializers only work when they are the rhs of an
> assign expression.

Now I get it. The struct initializer is an initializer, meaning that it's not an expression. Initializer can only appear as part of variable declarations. For example:

Test a;
a = {test: 1};

Doesn't compile either because `a = {test: 1};` is an assign expression and the struct initalizer is not an expression. I think this all could be simplified and indeed the struct initializer should be accepted as an expression, however, this is not a bug, rather an enhancement request.

If you are blocked by this, just use the default constructor:

struct Test
{
    int test;
}

struct Data
{
    Test[1] test;     // note that I changed this from Test[8] to Test[1]
                      // otherwise I had to put an array of 8 elements                                                                                                                                                                                               
}

void add(Data data)
{
}

void func(Test t) {}

extern(C) void main()
{

    Test a = {test: 1};

    add( Data(test: [ Test(1)] ) );
}
Comment 3 Nick Treleaven 2024-09-13 09:35:38 UTC
> `a = {test: 1};` is an assign expression and the struct initalizer is not an expression. I think this all could be simplified and indeed the struct initializer should be accepted as an expression

Well then the parser would have to look ahead in function literals for a semi-colon after an arbitrarily complex expression statement. Unless we make `{...}` not a function literal and require `(){...}`.