Skip to content

Commit facba98

Browse files
committed
fix #20610 aliasing for fields does not work
1 parent 2c5638e commit facba98

6 files changed

Lines changed: 85 additions & 16 deletions

File tree

compiler/src/dmd/declaration.d

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import dmd.func;
3030
import dmd.funcsem : overloadApply, getLevelAndCheck;
3131
import dmd.globals;
3232
import dmd.gluelayer;
33+
import dmd.hdrgen;
3334
import dmd.id;
3435
import dmd.identifier;
3536
import dmd.init;
@@ -442,16 +443,15 @@ extern (C++) final class AliasDeclaration : Declaration
442443
extern (D) this(const ref Loc loc, Identifier ident, Type type) @safe
443444
{
444445
super(loc, ident);
445-
//printf("AliasDeclaration(id = '%s', type = %p)\n", ident.toChars(), type);
446-
//printf("type = '%s'\n", type.toChars());
446+
//debug printf("AliasDeclaration(id = '%s', type = `%s`, %p)\n", ident.toChars(), dmd.hdrgen.toChars(type), type.isTypeIdentifier());
447447
this.type = type;
448448
assert(type);
449449
}
450450

451451
extern (D) this(const ref Loc loc, Identifier ident, Dsymbol s) @safe
452452
{
453453
super(loc, ident);
454-
//printf("AliasDeclaration(id = '%s', s = %p)\n", ident.toChars(), s);
454+
//debug printf("AliasDeclaration(id = '%s', s = `%s`)\n", ident.toChars(), s.toChars());
455455
assert(s != this);
456456
this.aliassym = s;
457457
assert(s);
@@ -612,8 +612,9 @@ extern (C++) final class AliasDeclaration : Declaration
612612

613613
override Dsymbol toAlias()
614614
{
615-
//printf("[%s] AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s', inuse = %d)\n",
616-
// loc.toChars(), toChars(), this, aliassym, aliassym ? aliassym.kind() : "", inuse);
615+
static if (0)
616+
printf("[%s] AliasDeclaration::toAlias('%s', this = %p, aliassym: %s, kind: '%s', inuse = %d)\n",
617+
loc.toChars(), toChars(), this, aliassym ? aliassym.toChars() : "", aliassym ? aliassym.kind() : "", inuse);
617618
assert(this != aliassym);
618619
//static int count; if (++count == 10) *(char*)0=0;
619620

compiler/src/dmd/dsymbolsem.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5243,7 +5243,7 @@ void aliasInstanceSemantic(TemplateInstance tempinst, Scope* sc, TemplateDeclara
52435243
// function used to perform semantic on AliasDeclaration
52445244
void aliasSemantic(AliasDeclaration ds, Scope* sc)
52455245
{
5246-
//printf("AliasDeclaration::semantic() %s\n", ds.toChars());
5246+
//printf("AliasDeclaration::semantic() %s %p\n", ds.toChars(), ds.aliassym);
52475247

52485248
// as DsymbolSemanticVisitor::visit(AliasDeclaration), in case we're called first.
52495249
// see https://issues.dlang.org/show_bug.cgi?id=21001

compiler/src/dmd/expressionsem.d

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8138,7 +8138,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
81388138
static if (LOGSEMANTIC)
81398139
{
81408140
printf("DotIdExp::semantic(this = %p, '%s')\n", exp, exp.toChars());
8141-
//printf("e1.op = %d, '%s'\n", e1.op, Token.toChars(e1.op));
8141+
printAST(exp);
81428142
}
81438143

81448144
if (sc.inCfile)
@@ -14037,7 +14037,7 @@ Expression expressionSemantic(Expression e, Scope* sc)
1403714037

1403814038
private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
1403914039
{
14040-
//printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars());
14040+
//printf("dotIdSemanticPropX() %s\n", toChars(exp));
1404114041
if (Expression ex = unaSemantic(exp, sc))
1404214042
return ex;
1404314043

@@ -14165,7 +14165,7 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
1416514165
*/
1416614166
Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag)
1416714167
{
14168-
//printf("DotIdExp::semanticY(this = %p, '%s')\n", exp, exp.toChars());
14168+
//printf("dotIdSemanticProp('%s')\n", exp.toChars());
1416914169

1417014170
//{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }
1417114171

@@ -14503,7 +14503,7 @@ Expression dotIdSemanticProp(DotIdExp exp, Scope* sc, bool gag)
1450314503

1450414504
const flag = cast(DotExpFlag) (exp.noderef * DotExpFlag.noDeref | gag * DotExpFlag.gag);
1450514505

14506-
Expression e = exp.e1.type.dotExp(sc, exp.e1, exp.ident, flag);
14506+
Expression e = dotExp(exp.e1.type, sc, exp.e1, exp.ident, flag);
1450714507
if (e)
1450814508
{
1450914509
e = e.expressionSemantic(sc);

compiler/src/dmd/printast.d

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ extern (C++) final class PrintASTVisitor : Visitor
5151
printf("%.*s %s\n", cast(int)s.length, s.ptr, e.type ? e.type.toChars() : "");
5252
}
5353

54+
override void visit(IdentifierExp e)
55+
{
56+
printIndent(indent);
57+
printf("Identifier `%s` %s\n", e.ident.toChars(), e.type ? e.type.toChars() : "");
58+
}
59+
5460
override void visit(IntegerExp e)
5561
{
5662
printIndent(indent);

compiler/src/dmd/typesem.d

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,6 +4462,10 @@ void resolve(Type mt, const ref Loc loc, Scope* sc, out Expression pe, out Type
44624462
*/
44634463
Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag flag)
44644464
{
4465+
enum LOGDOTEXP = false;
4466+
if (LOGDOTEXP)
4467+
printf("dotExp()\n");
4468+
44654469
Expression visitType(Type mt)
44664470
{
44674471
VarDeclaration v = null;
@@ -5082,8 +5086,41 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
50825086
return noMember(mt, sc, e, ident, flag);
50835087
}
50845088
// check before alias resolution; the alias itself might be deprecated!
5085-
if (s.isAliasDeclaration)
5089+
if (auto ad = s.isAliasDeclaration)
5090+
{
50865091
s.checkDeprecated(e.loc, sc);
5092+
5093+
// Fix for https://github.com/dlang/dmd/issues/20610
5094+
if (ad.originalType)
5095+
{
5096+
if (auto tid = ad.originalType.isTypeIdentifier())
5097+
{
5098+
if (tid.idents.length)
5099+
{
5100+
static if (0)
5101+
{
5102+
printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars());
5103+
printf("AliasDeclaration: %s\n", ad.toChars());
5104+
if (ad.aliassym)
5105+
printf("aliassym: %s\n", ad.aliassym.toChars());
5106+
printf("tid type: %s\n", toChars(tid));
5107+
}
5108+
/* Rewrite e.s as e.(tid.ident).(tid.idents)
5109+
*/
5110+
Expression die = new DotIdExp(e.loc, e, tid.ident);
5111+
foreach (id; tid.idents) // maybe use typeToExpressionHelper()
5112+
die = new DotIdExp(e.loc, die, cast(Identifier)id);
5113+
/* Ambiguous syntax, only way to disambiguate it to try it
5114+
*/
5115+
die = dmd.expressionsem.trySemantic(die, sc);
5116+
if (die && die.isDotVarExp()) // shrink wrap around DotVarExp()
5117+
{
5118+
return die;
5119+
}
5120+
}
5121+
}
5122+
}
5123+
}
50875124
s = s.toAlias();
50885125

50895126
if (auto em = s.isEnumMember())
@@ -6074,7 +6111,7 @@ Dsymbol toDsymbol(Type type, Scope* sc)
60746111

60756112
Dsymbol visitIdentifier(TypeIdentifier type)
60766113
{
6077-
//printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
6114+
//printf("TypeIdentifier::toDsymbol('%s')\n", toChars(type));
60786115
if (!sc)
60796116
return null;
60806117

@@ -6086,7 +6123,6 @@ Dsymbol toDsymbol(Type type, Scope* sc)
60866123
s = t.toDsymbol(sc);
60876124
if (e)
60886125
s = getDsymbol(e);
6089-
60906126
return s;
60916127
}
60926128

compiler/test/runnable/aliasassign.d

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ template Qual(alias T)
1515
alias Qual = T;
1616
}
1717

18-
void test()
18+
void test1()
1919
{
2020
int x = 3;
2121
int y = 4;
@@ -25,7 +25,33 @@ void test()
2525
assert(XY[1] == 4);
2626
}
2727

28-
void main()
28+
/**********************************************/
29+
30+
struct T
31+
{
32+
int k,i = 2;
33+
}
34+
35+
struct S
36+
{
37+
int x;
38+
T t;
39+
alias ti = t.i;
40+
}
41+
42+
void test2()
43+
{
44+
T t = T(1, 2);
45+
S s;
46+
assert(s.ti == 2);
47+
}
48+
49+
/**********************************************/
50+
51+
int main()
2952
{
30-
test();
53+
test1();
54+
test2();
55+
56+
return 0;
3157
}

0 commit comments

Comments
 (0)