Skip to content

Commit 4700925

Browse files
committed
[spec] Restore *ArrayInitializer*
It was merged with ArrayLiteral in #3215 (oops). Fixes Bugzilla 24634 - Parse error initializing array from expression with StructInitializer. Add examples.
1 parent 868574a commit 4700925

File tree

3 files changed

+70
-43
lines changed

3 files changed

+70
-43
lines changed

spec/arrays.dd

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,22 @@ int[]* e; // pointer to dynamic array of ints
107107
---------
108108
)
109109

110-
$(H2 $(LNAME2 literals, Array Literals))
110+
$(H2 $(LNAME2 literals, Array Initializers & Literals))
111111

112+
$(P An $(GLINK ArrayInitializer) initializes a dynamic or static array:)
112113
---
113114
auto a1 = [1,2,3]; // type is int[], with elements 1, 2, and 3
114115
auto a2 = [1u,2,3]; // type is uint[], with elements 1u, 2u, and 3u
115116
int[2] a3 = [1,2]; // type is int[2], with elements 1, and 2
116117
---
117-
$(P `[]` is an empty array literal.)
118118

119-
$(P See $(DDSUBLINK spec/expression, array_literals, Array Literals).)
119+
$(P An $(DDSUBLINK spec/expression, array_literals, array literal) is an expression:)
120+
---
121+
void f(int[] a);
122+
123+
f([1, 2]); // pass 2 elements
124+
f([]); // pass an empty array
125+
---
120126

121127
$(LEGACY_LNAME2 usage)
122128
$(H2 $(LNAME2 assignment, Array Assignment))
@@ -1010,8 +1016,23 @@ $(H3 $(LNAME2 void-initialization, Void Initialization))
10101016
$(REF uninitializedArray, std,array).
10111017
)
10121018

1019+
$(H3 $(LNAME2 array-initializers, Array Initializers))
1020+
1021+
$(GRAMMAR
1022+
$(GNAME ArrayInitializer):
1023+
$(D [) $(I ArrayElementInitializers)$(OPT) $(D ])
10131024

1014-
$(H3 $(LNAME2 static-init-static, Static Initialization of Statically Allocated Arrays))
1025+
$(GNAME ArrayElementInitializers):
1026+
$(I ArrayElementInitializer)
1027+
$(I ArrayElementInitializer) $(D ,)
1028+
$(I ArrayElementInitializer) $(D ,) $(GSELF ArrayElementInitializers)
1029+
1030+
$(GNAME ArrayElementInitializer):
1031+
$(GLINK2 declaration, NonVoidInitializer)
1032+
$(GLINK2 expression, AssignExpression) $(D :) $(GLINK2 declaration, NonVoidInitializer)
1033+
)
1034+
1035+
$(H4 $(LNAME2 static-init-static, Static Initialization of Statically Allocated Arrays))
10151036

10161037
$(P Static initalizations are supplied by a list of array
10171038
element values enclosed in `[ ]`. The values can be optionally
@@ -1057,6 +1078,30 @@ assert(a == [42, 42, 42, 42]);
10571078
Otherwise, they need to be marked with $(D const) or $(D static)
10581079
storage classes to make them statically allocated arrays.)
10591080

1081+
$(H4 $(LNAME2 index-initializers, Index Initializers))
1082+
1083+
$(P To initialize an element at a particular index, use the
1084+
*AssignExpression* `:` *NonVoidInitializer* syntax.
1085+
The *AssignExpression* must be known at compile-time.
1086+
Any missing elements will be initialized to the default value
1087+
of the element type.
1088+
Note that if the array type is not specified, the array initializer will
1089+
be parsed as an
1090+
$(DDSUBLINK spec/expression, associative_array_literals, associative array
1091+
literal).)
1092+
1093+
$(SPEC_RUNNABLE_EXAMPLE_RUN
1094+
---
1095+
int n = 4;
1096+
auto aa = [0:1, 3:n]; // associative array `int[int]`
1097+
1098+
int[] a = [1, 3:n, 5];
1099+
assert(a == [1, 0, 0, n, 5]);
1100+
1101+
//int[] e = [n:2]; // error, n not known at compile-time
1102+
---
1103+
)
1104+
10601105

10611106
$(H2 $(LNAME2 special-array, Special Array Types))
10621107

spec/declaration.dd

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,26 +183,38 @@ int x, *y; // x is an int, y is a pointer to int
183183
int x[], y; // x is an array/pointer, y is an int
184184
)
185185

186-
$(H2 $(LEGACY_LNAME2 initializers, initialization, Initialization))
186+
$(H2 $(LNAME2 initialization, Initialization))
187+
188+
$(P When no *Initializer* is given, a variable is set to the
189+
$(DDSUBLINK spec/property, init, default `.init` value) for
190+
its type.)
191+
192+
$(H3 $(LNAME2 initializers, Initializers))
187193

188194
$(GRAMMAR
189195
$(GNAME Initializer):
190196
$(GLINK VoidInitializer)
191197
$(GLINK NonVoidInitializer)
192198

193199
$(GNAME NonVoidInitializer):
194-
$(GLINK2 expression, AssignExpression)$(LEGACY_LNAME2 ExpInitializer)
195-
$(GLINK2 expression, ArrayLiteral)$(LEGACY_LNAME2 ArrayInitializer)
200+
$(GLINK2 arrays, ArrayInitializer)$(LEGACY_LNAME2 ArrayInitializer)
196201
$(GLINK2 struct, StructInitializer)$(LEGACY_LNAME2 StructInitializer)
202+
$(GLINK2 expression, AssignExpression)$(LEGACY_LNAME2 ExpInitializer)
197203
)
198204

199-
$(P When no *Initializer* is given, a variable is set to the
200-
$(DDSUBLINK spec/property, init, default `.init` value) for
201-
its type.)
205+
$(P A variable can be initialized with a $(I NonVoidInitializer).
206+
An *ArrayInitializer* or *StructInitializer* takes precedence over
207+
an expression initializer.)
202208

203-
$(P A variable can be initialized with a $(I NonVoidInitializer).)
209+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
210+
---
211+
struct S { int i; }
204212

205-
$(P See also: $(DDSUBLINK spec/arrays, array-initialization, Array Initialization).)
213+
S s = {}; // struct initializer, not a function literal expression
214+
S[] a = [{2}]; // array initializer holding a struct initializer
215+
//a = [{2}]; // invalid array literal expression
216+
---
217+
)
206218

207219
$(H3 $(LNAME2 void_init, Void Initialization))
208220

spec/expression.dd

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,16 +2101,7 @@ $(H3 $(LNAME2 array_literals, Array Literals))
21012101

21022102
$(GRAMMAR
21032103
$(GNAME ArrayLiteral):
2104-
$(D [) $(I ArrayMemberInitializations)$(OPT) $(D ])
2105-
2106-
$(GNAME ArrayMemberInitializations):
2107-
$(I ArrayMemberInitialization)
2108-
$(I ArrayMemberInitialization) $(D ,)
2109-
$(I ArrayMemberInitialization) $(D ,) $(GSELF ArrayMemberInitializations)
2110-
2111-
$(GNAME ArrayMemberInitialization):
2112-
$(GLINK2 declaration, NonVoidInitializer)
2113-
$(GLINK AssignExpression) $(D :) $(GLINK2 declaration, NonVoidInitializer)
2104+
$(D [) $(GLINK ArgumentList)$(OPT) $(D ])
21142105
)
21152106

21162107
$(P An array literal is a comma-separated list of expressions
@@ -2162,27 +2153,6 @@ $(GNAME ArrayMemberInitialization):
21622153
}
21632154
---
21642155

2165-
$(P To initialize an element at a particular index, use the
2166-
*AssignExpression* `:` *NonVoidInitializer* syntax.
2167-
The *AssignExpression* must be known at compile-time.
2168-
Any missing elements will be initialized to the default value
2169-
of the element type.
2170-
Note that if the array type is not specified, the literal will
2171-
be parsed as an
2172-
$(RELATIVE_LINK2 associative_array_literals, associative array).)
2173-
2174-
$(SPEC_RUNNABLE_EXAMPLE_RUN
2175-
---
2176-
int n = 4;
2177-
auto aa = [0:1, 3:n]; // associative array `int[int]`
2178-
2179-
int[] a = [1, 3:n, 5];
2180-
assert(a == [1, 0, 0, n, 5]);
2181-
2182-
//int[] e = [n:2]; // error, n not known at compile-time
2183-
---
2184-
)
2185-
21862156
$(H4 $(LNAME2 cast_array_literal, Casting))
21872157

21882158
$(P When array literals are cast to another array type, each

0 commit comments

Comments
 (0)