Skip to content

Commit

Permalink
Merge pull request #5123 from 9rnsr/fix15065
Browse files Browse the repository at this point in the history
Issue 15065 - associative array has no keys property
  • Loading branch information
MartinNowak committed Sep 27, 2015
2 parents cfb9668 + 609654e commit 7a7687e
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 178 deletions.
249 changes: 71 additions & 178 deletions src/mtype.d
Expand Up @@ -2725,6 +2725,10 @@ public:
return id;
}

/***************************************
* Resolve 'this' type to either type, symbol, or expression.
* If errors happened, resolved to Type.terror.
*/
void resolve(Loc loc, Scope* sc, Expression* pe, Type* pt, Dsymbol* ps, bool intypeid = false)
{
//printf("Type::resolve() %s, %d\n", toChars(), ty);
Expand Down Expand Up @@ -6905,46 +6909,43 @@ public:
*pt = (*pt).semantic(loc, sc);
}

final void resolveExprType(Loc loc, Scope* sc, Expression e, size_t i, Expression* pe, Type* pt)
final Expression toExpressionHelper(Expression e, size_t i = 0)
{
//printf("resolveExprType(e = %s %s, type = %s)\n", Token::toChars(e->op), e->toChars(), e->type->toChars());
e = e.semantic(sc);
//printf("toExpressionHelper(e = %s %s)\n", Token.toChars(e.op), e.toChars());
for (; i < idents.dim; i++)
{
if (e.op == TOKerror)
break;
RootObject id = idents[i];
//printf("e: '%s', id: '%s', type = %s\n", e->toChars(), id->toChars(), e->type->toChars());
if (id.dyncast() == DYNCAST_IDENTIFIER)
{
auto die = new DotIdExp(e.loc, e, cast(Identifier)id);
e = die.semanticY(sc, 0);
}
else if (id.dyncast() == DYNCAST_TYPE) // Bugzilla 1215
{
e = new IndexExp(loc, e, new TypeExp(loc, cast(Type)id));
e = e.semantic(sc);
}
else if (id.dyncast() == DYNCAST_EXPRESSION) // Bugzilla 1215
{
e = new IndexExp(loc, e, cast(Expression)id);
e = e.semantic(sc);
}
else
//printf("\t[%d] e: '%s', id: '%s'\n", i, e.toChars(), id.toChars());

switch (id.dyncast())
{
assert(id.dyncast() == DYNCAST_DSYMBOL);
TemplateInstance ti = (cast(Dsymbol)id).isTemplateInstance();
assert(ti);
auto dte = new DotTemplateInstanceExp(e.loc, e, ti.name, ti.tiargs);
e = dte.semanticY(sc, 0);
// ... '. ident'
case DYNCAST_IDENTIFIER:
e = new DotIdExp(e.loc, e, cast(Identifier)id);
break;

// ... '. name!(tiargs)'
case DYNCAST_DSYMBOL:
auto ti = (cast(Dsymbol)id).isTemplateInstance();
assert(ti);
e = new DotTemplateInstanceExp(e.loc, e, ti.name, ti.tiargs);
break;

// ... '[type]'
case DYNCAST_TYPE: // Bugzilla 1215
e = new ArrayExp(loc, e, new TypeExp(loc, cast(Type)id));
break;

// ... '[expr]'
case DYNCAST_EXPRESSION: // Bugzilla 1215
e = new ArrayExp(loc, e, cast(Expression)id);
break;

default:
assert(0);
}
}
if (e.op == TOKerror)
*pt = Type.terror;
else if (e.op == TOKtype)
*pt = e.type;
else
*pe = e;
return e;
}

/*************************************
Expand All @@ -6954,7 +6955,8 @@ public:
* if expression, *pe is set
* if type, *pt is set
*/
final void resolveHelper(Loc loc, Scope* sc, Dsymbol s, Dsymbol scopesym, Expression* pe, Type* pt, Dsymbol* ps, bool intypeid = false)
final void resolveHelper(Loc loc, Scope* sc, Dsymbol s, Dsymbol scopesym,
Expression* pe, Type* pt, Dsymbol* ps, bool intypeid = false)
{
version (none)
{
Expand Down Expand Up @@ -6992,7 +6994,15 @@ public:
if (tx)
ex = new TypeExp(loc, tx);
assert(ex);
resolveExprType(loc, sc, ex, i + 1, pe, pt);

ex = toExpressionHelper(ex, i + 1);
ex = ex.semantic(sc);
if (ex.op == TOKerror)
*pt = Type.terror;
else if (ex.op == TOKtype)
*pt = ex.type;
else if ((*ps = getDsymbol(ex)) is null)
*pe = ex;
return;
}
Type t = s.getType(); // type symbol, type alias, or type tuple?
Expand Down Expand Up @@ -7047,7 +7057,15 @@ public:
e = DsymbolExp.resolve(loc, sc, s, false);
else
e = new VarExp(loc, s.isDeclaration());
resolveExprType(loc, sc, e, i, pe, pt);

e = toExpressionHelper(e, i);
e = e.semantic(sc);
if (e.op == TOKerror)
*pt = Type.terror;
else if (e.op == TOKtype)
*pt = e.type;
else if ((*ps = getDsymbol(e)) is null)
*pe = e;
return;
}
else
Expand Down Expand Up @@ -7320,39 +7338,7 @@ public:

override Expression toExpression()
{
Expression e = new IdentifierExp(loc, ident);
for (size_t i = 0; i < idents.dim; i++)
{
RootObject id = idents[i];
switch (id.dyncast())
{
case DYNCAST_IDENTIFIER:
{
e = new DotIdExp(loc, e, cast(Identifier)id);
break;
}
case DYNCAST_DSYMBOL:
{
TemplateInstance ti = (cast(Dsymbol)id).isTemplateInstance();
assert(ti);
e = new DotTemplateInstanceExp(loc, e, ti.name, ti.tiargs);
break;
}
case DYNCAST_TYPE:
{
e = new ArrayExp(loc, e, new TypeExp(loc, cast(Type)id));
break;
}
case DYNCAST_EXPRESSION:
{
e = new ArrayExp(loc, e, cast(Expression)id);
break;
}
default:
assert(0);
}
}
return e;
return toExpressionHelper(new IdentifierExp(loc, ident));
}

override void accept(Visitor v)
Expand Down Expand Up @@ -7465,39 +7451,7 @@ public:

override Expression toExpression()
{
Expression e = new ScopeExp(loc, tempinst);
for (size_t i = 0; i < idents.dim; i++)
{
RootObject id = idents[i];
switch (id.dyncast())
{
case DYNCAST_IDENTIFIER:
{
e = new DotIdExp(loc, e, cast(Identifier)id);
break;
}
case DYNCAST_DSYMBOL:
{
TemplateInstance ti = (cast(Dsymbol)id).isTemplateInstance();
assert(ti);
e = new DotTemplateInstanceExp(loc, e, ti.name, ti.tiargs);
break;
}
case DYNCAST_TYPE:
{
e = new ArrayExp(loc, e, new TypeExp(loc, cast(Type)id));
break;
}
case DYNCAST_EXPRESSION:
{
e = new ArrayExp(loc, e, cast(Expression)id);
break;
}
default:
assert(0);
}
}
return e;
return toExpressionHelper(new ScopeExp(loc, tempinst));
}

override void accept(Visitor v)
Expand Down Expand Up @@ -7613,45 +7567,14 @@ public:
resolveHelper(loc, sc, s, null, pe, pt, ps, intypeid);
else
{
Expression e = new TypeExp(loc, t);
for (size_t i = 0; i < idents.dim; i++)
{
RootObject id = idents[i];
switch (id.dyncast())
{
case DYNCAST_IDENTIFIER:
{
e = new DotIdExp(loc, e, cast(Identifier)id);
break;
}
case DYNCAST_DSYMBOL:
{
TemplateInstance ti = (cast(Dsymbol)id).isTemplateInstance();
e = new DotExp(loc, e, new ScopeExp(loc, ti));
break;
}
case DYNCAST_TYPE:
{
e = new ArrayExp(loc, e, new TypeExp(loc, cast(Type)id));
break;
}
case DYNCAST_EXPRESSION:
{
e = new ArrayExp(loc, e, cast(Expression)id);
break;
}
default:
assert(0);
}
}
auto e = toExpressionHelper(new TypeExp(loc, t));
e = e.semantic(sc);
if ((*ps = getDsymbol(e)) is null)
{
if (e.op == TOKtype)
*pt = e.type;
else
*pe = e;
}
if (e.op == TOKerror)
goto Lerr;
else if (e.op == TOKtype)
*pt = e.type;
else if ((*ps = getDsymbol(e)) is null)
*pe = e;
}
}
if (*pt)
Expand Down Expand Up @@ -7754,50 +7677,20 @@ public:
resolveHelper(loc, sc, s, null, pe, pt, ps, intypeid);
else
{
Expression e = new TypeExp(loc, t);
for (size_t i = 0; i < idents.dim; i++)
{
RootObject id = idents[i];
switch (id.dyncast())
{
case DYNCAST_IDENTIFIER:
{
e = new DotIdExp(loc, e, cast(Identifier)id);
break;
}
case DYNCAST_DSYMBOL:
{
TemplateInstance ti = (cast(Dsymbol)id).isTemplateInstance();
e = new DotExp(loc, e, new ScopeExp(loc, ti));
break;
}
case DYNCAST_TYPE:
{
e = new ArrayExp(loc, e, new TypeExp(loc, cast(Type)id));
break;
}
case DYNCAST_EXPRESSION:
{
e = new ArrayExp(loc, e, cast(Expression)id);
break;
}
default:
assert(0);
}
}
auto e = toExpressionHelper(new TypeExp(loc, t));
e = e.semantic(sc);
if ((*ps = getDsymbol(e)) is null)
{
if (e.op == TOKtype)
*pt = e.type;
else
*pe = e;
}
if (e.op == TOKerror)
goto Lerr;
else if (e.op == TOKtype)
*pt = e.type;
else if ((*ps = getDsymbol(e)) is null)
*pe = e;
}
}
if (*pt)
(*pt) = (*pt).addMod(mod);
return;

Lerr:
*pt = Type.terror;
return;
Expand Down
14 changes: 14 additions & 0 deletions test/runnable/ufcs.d
Expand Up @@ -809,6 +809,20 @@ void test11312()
assert(x == 10);
}

/*******************************************/
// 15123

auto keys15123(K, V)(V[K] aa) { return [1]; }
auto values15123(K, V)(V[K] aa) { return [2]; }

alias id15123(alias arg) = arg;

enum int[int] aa15123 = [1:2];
static assert(id15123!(aa15123.keys15123) == [1]); // TypeIdentifier + UFCS

T[T] f15123(T)() { return [1:2]; }
static assert(id15123!(f15123!int.values15123) == [2]); // TypeInstance + UFCS

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

int main()
Expand Down

0 comments on commit 7a7687e

Please sign in to comment.