Skip to content

Commit 3d3c547

Browse files
authored
fix dlang#17804 multi-dimensional AA is not an initializer (dlang#21773)
assume an array literal initializer that looks like an AA is only a dynamic array if a respective type is provided (as expressions already do)
1 parent 956b43d commit 3d3c547

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

compiler/src/dmd/dsymbolsem.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
16501650
if (ai && tb.ty == Taarray)
16511651
e = ai.toAssocArrayLiteral();
16521652
else
1653-
e = dsym._init.initializerToExpression(null, sc.inCfile);
1653+
e = dsym._init.initializerToExpression(dsym.type, sc.inCfile);
16541654
if (!e)
16551655
{
16561656
// Run semantic, but don't need to interpret

compiler/src/dmd/initsem.d

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
168168
// Convert initializer to Expression `ex`
169169
auto tm = fieldType.addMod(t.mod);
170170
auto iz = i.value[j].initializerSemantic(sc, tm, needInterpret);
171-
auto ex = iz.initializerToExpression(null, sc.inCfile);
171+
auto ex = iz.initializerToExpression(fieldType, sc.inCfile);
172172
if (ex.op != EXP.error)
173173
i.value[j] = iz;
174174
return ex;
@@ -1267,6 +1267,11 @@ Expression initializerToExpression(Initializer init, Type itype = null, const bo
12671267
{
12681268
//printf("ArrayInitializer::toExpression(), dim = %d\n", dim);
12691269
//static int i; if (++i == 2) assert(0);
1270+
if (!itype || itype.toBasetype().isTypeAArray())
1271+
if (!init.type || init.type.isTypeAArray())
1272+
if (init.isAssociativeArray())
1273+
return init.toAssocArrayLiteral();
1274+
12701275
uint edim; // the length of the resulting array literal
12711276
const(uint) amax = 0x80000000;
12721277
Type t = null; // type of the array literal being initialized

compiler/test/runnable/staticaa.d

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,16 +209,49 @@ void testClassLiteral()
209209
// https://github.com/dlang/dmd/issues/21690
210210
void testMultiDim()
211211
{
212-
// int[int][int] aa1 = [ 1: [2: 3] ]; // Error: invalid value `[2:3]` in initializer (see #17804)
212+
int[int][int] aa1 = [ 1: [2: 3] ]; // Error: invalid value `[2:3]` in initializer (see #17804)
213213
int[int][int] aa2 = ([ 1: [2: 3] ]); // workaround
214214
auto aa3 = [ 1: [2: 3] ]; // works, too
215215
static auto aa4 = [ 1: [2: 3] ]; // Error: internal compiler error: failed to detect static initialization of associative array
216+
assert(aa1 == aa2);
216217
assert(aa2 == aa3);
217218
assert(aa3 == aa4);
218219
}
219220

220221
/////////////////////////////////////////////
221222

223+
// https://github.com/dlang/dmd/issues/17804
224+
void testMultiDimInit()
225+
{
226+
static struct D
227+
{
228+
string[string][string] aa;
229+
this(string[string][string] _aa) { aa = _aa; }
230+
}
231+
static struct S
232+
{
233+
//Error: not an associative array initializer
234+
D a = ["fdsa": ["fdsafd": "fdsfa"]];
235+
236+
// OK
237+
D b = (["fdsa": ["fdsafd": "fdsfa"]]);
238+
}
239+
immutable string[7] a = [
240+
3 : null,
241+
2 : "D",
242+
1 : "C",
243+
];
244+
static int[char][char] arr = ['A' : ['B': 0]]; // error
245+
assert(arr.length == 1);
246+
assert(arr['A'] == ['B':0]);
247+
248+
S s;
249+
assert(s.a.aa["fdsa"]["fdsafd"] == "fdsfa");
250+
assert(s.b.aa["fdsa"]["fdsafd"] == "fdsfa");
251+
}
252+
253+
/////////////////////////////////////////////
254+
222255
void main()
223256
{
224257
testSimple();
@@ -232,4 +265,5 @@ void main()
232265
testStaticArray();
233266
testClassLiteral();
234267
testMultiDim();
268+
testMultiDimInit();
235269
}

0 commit comments

Comments
 (0)