Skip to content

Commit

Permalink
Merge pull request #8846 from RazvanN7/Issue_16633
Browse files Browse the repository at this point in the history
Fix Issue 16633 - Case where an alias this is tried before the object itself
  • Loading branch information
thewilsonator committed Nov 5, 2018
2 parents 08e4d82 + d6c255b commit 7c2a70a
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 2 deletions.
50 changes: 50 additions & 0 deletions src/dmd/expressionsem.d
Expand Up @@ -8705,9 +8705,59 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
// Try alias this on first operand
static Expression tryAliasThisForLhs(BinAssignExp exp, Scope* sc)
{
AggregateDeclaration ad1 = isAggregate(exp.e1.type);
if (!ad1 || !ad1.aliasthis)
return null;

/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
if (exp.att1 && exp.e1.type == exp.att1)
return null;
//printf("att %s e1 = %s\n", Token::toChars(e.op), e.e1.type.toChars());
Expression e1 = new DotIdExp(exp.loc, exp.e1, ad1.aliasthis.ident);
BinExp be = cast(BinExp)exp.copy();
if (!be.att1 && exp.e1.type.checkAliasThisRec())
be.att1 = exp.e1.type;
be.e1 = e1;
return be.trySemantic(sc);
}

// Try alias this on second operand
static Expression tryAliasThisForRhs(BinAssignExp exp, Scope* sc)
{
AggregateDeclaration ad2 = isAggregate(exp.e2.type);
if (!ad2 || !ad2.aliasthis)
return null;
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
if (exp.att2 && exp.e2.type == exp.att2)
return null;
//printf("att %s e2 = %s\n", Token::toChars(e.op), e.e2.type.toChars());
Expression e2 = new DotIdExp(exp.loc, exp.e2, ad2.aliasthis.ident);
BinExp be = cast(BinExp)exp.copy();
if (!be.att2 && exp.e2.type.checkAliasThisRec())
be.att2 = exp.e2.type;
be.e2 = e2;
return be.trySemantic(sc);
}

result = tryAliasThisForLhs(exp, sc);
if (result)
return;

result = tryAliasThisForRhs(exp, sc);
if (result)
return;

exp.error("cannot append type `%s` to type `%s`", tb2.toChars(), tb1.toChars());
return setError();
}

if (exp.e2.checkValue())
return setError();

Expand Down
18 changes: 16 additions & 2 deletions src/dmd/opover.d
Expand Up @@ -456,7 +456,14 @@ private Expression checkAliasThisForLhs(AggregateDeclaration ad, Scope* sc, BinE
if (!be.att1 && e.e1.type.checkAliasThisRec())
be.att1 = e.e1.type;
be.e1 = e1;
return be.trySemantic(sc);

Expression result;
if (be.op == TOK.concatenateAssign)
result = be.op_overload(sc);
else
result = be.trySemantic(sc);

return result;
}

// Try alias this on second operand
Expand All @@ -475,7 +482,14 @@ private Expression checkAliasThisForRhs(AggregateDeclaration ad, Scope* sc, BinE
if (!be.att2 && e.e2.type.checkAliasThisRec())
be.att2 = e.e2.type;
be.e2 = e2;
return be.trySemantic(sc);

Expression result;
if (be.op == TOK.concatenateAssign)
result = be.op_overload(sc);
else
result = be.trySemantic(sc);

return result;
}

/************************************
Expand Down
20 changes: 20 additions & 0 deletions test/runnable/aliasthis.d
Expand Up @@ -2057,6 +2057,25 @@ void test19284()
assert(t.x == 5);
}

// 16633

class Item
{
alias children this;
Item[] children;
void populate()
{
children ~= new Item(); // Item is seen as []
assert(children.length == 1);
}
}

void test16633()
{
Item root = new Item();
root.populate;
}

int main()
{
test1();
Expand Down Expand Up @@ -2114,6 +2133,7 @@ int main()
test11355();
test14806();
test19284();
test16633();

printf("Success\n");
return 0;
Expand Down

0 comments on commit 7c2a70a

Please sign in to comment.