Skip to content

Commit

Permalink
Fix Issue 16082 and 16086
Browse files Browse the repository at this point in the history
  • Loading branch information
RazvanN7 committed Oct 29, 2018
1 parent b6f2417 commit 80ec7d9
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 22 deletions.
77 changes: 77 additions & 0 deletions src/dmd/dscope.d
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import dmd.doc;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.expression;
import dmd.errors;
import dmd.func;
import dmd.globals;
Expand Down Expand Up @@ -365,6 +366,70 @@ struct Scope
return null;
}

Dsymbol checkAliasThis(AggregateDeclaration ad, Identifier ident, int flags, Expression* exp)
{
import dmd.mtype;
if (!ad || !ad.aliasthis)
return null;

Declaration decl = ad.aliasthis.isDeclaration();
if (!decl)
return null;

Type t = decl.type;
ScopeDsymbol sds;
TypeClass tc;
TypeStruct ts;
switch(t.ty)
{
case Tstruct:
ts = cast(TypeStruct)t;
sds = ts.sym;
break;
case Tclass:
tc = cast(TypeClass)t;
sds = tc.sym;
break;
case Tinstance:
sds = (cast(TypeInstance)t).tempinst;
break;
case Tenum:
sds = (cast(TypeEnum)t).sym;
break;
default: break;
}

if (!sds)
return null;

Dsymbol ret = sds.search(loc, ident, flags);
if (ret)
{
*exp = new DotIdExp(loc, *exp, ad.aliasthis.ident);
*exp = new DotIdExp(loc, *exp, ident);
return ret;
}

if (!ts && !tc)
return null;

Dsymbol s;
*exp = new DotIdExp(loc, *exp, ad.aliasthis.ident);
if (ts && !(ts.att & AliasThisRec.tracing))
{
ts.att = cast(AliasThisRec)(ts.att | AliasThisRec.tracing);
s = checkAliasThis(sds.isAggregateDeclaration(), ident, flags, exp);
ts.att = cast(AliasThisRec)(ts.att & ~AliasThisRec.tracing);
}
else if(tc && !(tc.att & AliasThisRec.tracing))
{
tc.att = cast(AliasThisRec)(tc.att | AliasThisRec.tracing);
s = checkAliasThis(sds.isAggregateDeclaration(), ident, flags, exp);
tc.att = cast(AliasThisRec)(tc.att & ~AliasThisRec.tracing);
}
return s;
}

Dsymbol searchScopes(int flags)
{
for (Scope* sc = &this; sc; sc = sc.enclosing)
Expand All @@ -390,6 +455,18 @@ struct Scope
*pscopesym = sc.scopesym;
return s;
}

Expression exp = new ThisExp(loc);
Dsymbol aliasSym = checkAliasThis(sc.scopesym.isAggregateDeclaration(), ident, flags, &exp);
//printf("exp = %s\n", exp.toChars());
if (aliasSym)
{
//printf("found aliassym: %s\n", aliasSym.toChars());
if (pscopesym)
*pscopesym = new ExpressionDsymbol(exp);
return aliasSym;
}

// Stop when we hit a module, but keep going if that is not just under the global scope
if (sc.scopesym.isModule() && !(sc.enclosing && !sc.enclosing.enclosing))
break;
Expand Down
25 changes: 25 additions & 0 deletions src/dmd/dsymbol.d
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,11 @@ extern (C++) class Dsymbol : RootObject
return null;
}

inout(ExpressionDsymbol) isExpressionDsymbol() inout
{
return null;
}

inout(ThisDeclaration) isThisDeclaration() inout
{
return null;
Expand Down Expand Up @@ -2051,6 +2056,26 @@ extern (C++) final class ForwardingScopeDsymbol : ScopeDsymbol

}

/**
* Class that holds an expression in a Dsymbol wraper.
* This is not an AST node, but a class used to pass
* an expression as a function parameter of type Dsymbol.
*/
extern (C++) final class ExpressionDsymbol : Dsymbol
{
Expression exp;
this(Expression exp)
{
super();
this.exp = exp;
}

override inout(ExpressionDsymbol) isExpressionDsymbol() inout
{
return this;
}
}


/***********************************************************
* Table of Dsymbol's
Expand Down
27 changes: 9 additions & 18 deletions src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -2348,29 +2348,20 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
}
// Haven't done overload resolution yet, so pass 1
e = resolve(exp.loc, sc, s, true);
}
result = e;
return;
}

if (hasThis(sc))
{
AggregateDeclaration ad = sc.getStructClassScope();
if (ad && ad.aliasthis)
{
Expression e;
e = new ThisExp(exp.loc);
e = new DotIdExp(exp.loc, e, ad.aliasthis.ident);
e = new DotIdExp(exp.loc, e, exp.ident);
e = e.trySemantic(sc);
if (e)
ExpressionDsymbol expDsym = scopesym.isExpressionDsymbol();
if (expDsym)
{
result = e;
//printf("expDsym = %s\n", expDsym.exp.toChars());
result = expDsym.exp.expressionSemantic(sc);
return;
}

// Haven't done overload resolution yet, so pass 1
e = resolve(exp.loc, sc, s, true);
}
result = e;
return;
}

if (exp.ident == Id.ctfe)
Expand Down
4 changes: 1 addition & 3 deletions test/fail_compilation/test17380spec.d
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/* REQUIRED_ARGS: -verrors=spec
TEST_OUTPUT:
---
(spec:1) fail_compilation/test17380spec.d(14): Error: cannot resolve identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
(spec:1) fail_compilation/test17380spec.d(14): Error: no property `ThisTypeDoesNotExistAndCrashesTheCompiler` for type `Uint128`
fail_compilation/test17380spec.d(14): Error: undefined identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
fail_compilation/test17380spec.d(12): Error: undefined identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
---
*/

Expand Down
70 changes: 70 additions & 0 deletions test/runnable/aliasthis.d
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module aliasthis;

extern (C) int printf(const(char*) fmt, ...);
import core.vararg;
Expand Down Expand Up @@ -2057,6 +2058,73 @@ void test19284()
assert(t.x == 5);
}

// https://issues.dlang.org/show_bug.cgi?id=16086
import std.range;

struct S16086
{
struct Inner2
{
Inner a;
alias a this;
}

struct Inner
{
int unique_identifier_name;
int tail = 2;
}

Inner2 inner;
alias inner this;

auto works()
{
return unique_identifier_name;
}

auto fails()
{
int a = tail;
return tail; // Line 22
// The workaround: return this.tail;
}
}

void test16086()
{
S16086 s;
assert(s.fails == 2);
}

// https://issues.dlang.org/show_bug.cgi?id=16082
struct S16082
{
struct Inner
{
int any_name_but_modulename;
int aliasthis = 5;
}

Inner inner;
alias inner this;

auto works()
{
return any_name_but_modulename;
}
auto fails()
{
return aliasthis; // Line 20
}
}

void test16082()
{
S16082 s;
assert(s.fails == 5);
}

int main()
{
test1();
Expand Down Expand Up @@ -2114,6 +2182,8 @@ int main()
test11355();
test14806();
test19284();
test16086();
test16082();

printf("Success\n");
return 0;
Expand Down
2 changes: 1 addition & 1 deletion test/runnable/imports/a12037.d
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private:
// Convert F to the correct binary type.
static typeof(get) opCall(F value)
{
ToBinary r;
ToBinary!F r;
r.set = value;
return r.get;
}
Expand Down

0 comments on commit 80ec7d9

Please sign in to comment.