Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 8557 - AA error with string[string][] #2876

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/declaration.c
Expand Up @@ -1385,7 +1385,7 @@ void VarDeclaration::semantic(Scope *sc)
ArrayInitializer *ai = init->isArrayInitializer();
if (ai && tb->ty == Taarray)
{
Expression *e = ai->toAssocArrayLiteral();
Expression *e = ai->toAssocArrayLiteral(tb);
init = new ExpInitializer(e->loc, e);
}

Expand Down
41 changes: 21 additions & 20 deletions src/init.c
Expand Up @@ -403,7 +403,7 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, NeedInterpret needIn

case Taarray:
// was actually an associative array literal
aa = new ExpInitializer(loc, toAssocArrayLiteral());
aa = new ExpInitializer(loc, toAssocArrayLiteral(t));
return aa->semantic(sc, t, needInterpret);

default:
Expand Down Expand Up @@ -500,6 +500,8 @@ Expression *ArrayInitializer::toExpression(Type *tx)
Expressions *elements;
size_t edim;
Type *t = NULL;
if (!type)
type = tx;
if (type)
{
if (type == Type::terror)
Expand All @@ -508,17 +510,19 @@ Expression *ArrayInitializer::toExpression(Type *tx)
t = type->toBasetype();
switch (t->ty)
{
case Tsarray:
edim = (size_t)((TypeSArray *)t)->dim->toInteger();
break;
case Tsarray:
edim = (size_t)((TypeSArray *)t)->dim->toInteger();
break;

case Tpointer:
case Tarray:
edim = dim;
break;
case Tpointer:
case Tarray:
edim = dim;
break;

default:
assert(0);
case Taarray:
return toAssocArrayLiteral(type);
default:
assert(0);
}
}
else
Expand All @@ -527,12 +531,7 @@ Expression *ArrayInitializer::toExpression(Type *tx)
for (size_t i = 0, j = 0; i < value.dim; i++, j++)
{
if (index[i])
{
if (index[i]->op == TOKint64)
j = (size_t)index[i]->toInteger();
else
goto Lno;
}
return toAssocArrayLiteral();
if (j >= edim)
edim = j + 1;
}
Expand All @@ -549,7 +548,8 @@ Expression *ArrayInitializer::toExpression(Type *tx)
Initializer *iz = value[i];
if (!iz)
goto Lno;
Expression *ex = iz->toExpression();
Type *tn = type ? type->nextOf() : NULL;
Expression *ex = iz->toExpression(tn);
if (!ex)
{
goto Lno;
Expand Down Expand Up @@ -593,11 +593,11 @@ Expression *ArrayInitializer::toExpression(Type *tx)
* If possible, convert array initializer to associative array initializer.
*/

Expression *ArrayInitializer::toAssocArrayLiteral()
Expression *ArrayInitializer::toAssocArrayLiteral(Type *t)
{
Expression *e;

//printf("ArrayInitializer::toAssocArrayInitializer()\n");
//printf("ArrayInitializer::toAssocArrayLiteral()\n");
//static int i; if (++i == 2) halt();
Expressions *keys = new Expressions();
keys->setDim(value.dim);
Expand All @@ -614,7 +614,8 @@ Expression *ArrayInitializer::toAssocArrayLiteral()
Initializer *iz = value[i];
if (!iz)
goto Lno;
e = iz->toExpression();
Type *tn = t ? t->nextOf() : NULL;
e = iz->toExpression(tn);
if (!e)
goto Lno;
(*values)[i] = e;
Expand Down
2 changes: 1 addition & 1 deletion src/init.h
Expand Up @@ -118,7 +118,7 @@ class ArrayInitializer : public Initializer
int isAssociativeArray();
Type *inferType(Scope *sc);
Expression *toExpression(Type *t = NULL);
Expression *toAssocArrayLiteral();
Expression *toAssocArrayLiteral(Type *t = NULL);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);

dt_t *toDt();
Expand Down
16 changes: 16 additions & 0 deletions test/runnable/xtest46.d
Expand Up @@ -2256,6 +2256,22 @@ void test658()

/***************************************************/

void test8557()
{
auto a5 = [["A": "B"], ["C": "D"]];
static assert(is(typeof(a5) == string[string][]));
int[char][char] foo1 = ['A': ['B': 1]]; //rejects-valid
int[char][char] foo2 = cast()['A': ['B': 1]]; //workaround
auto foo3 = ['A' : ['B': 1]];
static assert(is(typeof(foo3) == int[char][char]));
auto foo4 = ['A' : [3, 1]];
static assert(is(typeof(foo4) == int[][char]));
auto foo5 = ['A' : [3 : 1]];
static assert(is(typeof(foo5) == int[int][char]));
}

/***************************************************/

void test3069()
{
ubyte id = 0;
Expand Down