Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void functionToCBuffer2(TypeFunction *t, OutBuffer *buf, HdrGenState *hgs, int m
*/

Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
Expression *e1, Declaration *var)
Expression *e1, Declaration *var, int flag = 0)
{
//printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1->toChars(), ad->toChars(), var->toChars());
L1:
Expand Down Expand Up @@ -85,7 +85,8 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
* member pointing to the enclosing class instance
*/
if (tcd && tcd->isNested())
{ /* e1 is the 'this' pointer for an inner class: tcd.
{
/* e1 is the 'this' pointer for an inner class: tcd.
* Rewrite it as the 'this' pointer for the outer class.
*/

Expand All @@ -102,7 +103,8 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
for (s = tcd->toParent();
s && s->isFuncDeclaration();
s = s->toParent())
{ FuncDeclaration *f = s->isFuncDeclaration();
{
FuncDeclaration *f = s->isFuncDeclaration();
if (f->vthis)
{
//printf("rewriting e1 to %s's this\n", f->toChars());
Expand All @@ -119,7 +121,8 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
}
}
if (s && s->isClassDeclaration())
{ e1->type = s->isClassDeclaration()->type;
{
e1->type = s->isClassDeclaration()->type;
e1->type = e1->type->addMod(t->mod);
if (n > 1)
e1 = e1->semantic(sc);
Expand All @@ -128,11 +131,14 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
e1 = e1->semantic(sc);
goto L1;
}

/* Can't find a path from e1 to ad
*/
if (flag)
return NULL;
e1->error("this for %s needs to be type %s not type %s",
var->toChars(), ad->toChars(), t->toChars());
e1 = new ErrorExp();
return new ErrorExp();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope that error propagation will make these kind of flags and the gagging superfluous at some point.

}
}
return e1;
Expand Down Expand Up @@ -7885,7 +7891,17 @@ Expression *DotVarExp::semantic(Scope *sc)

Dsymbol *vparent = var->toParent();
AggregateDeclaration *ad = vparent ? vparent->isAggregateDeclaration() : NULL;
e1 = getRightThis(loc, sc, ad, e1, var);

if (Expression *e1x = getRightThis(loc, sc, ad, e1, var, 1))
e1 = e1x;
else
{
/* Later checkRightThis will report correct error for invalid field variable access.
*/
Expression *e = new VarExp(loc, var);
e = e->semantic(sc);
return e;
}
accessCheck(loc, sc, e1, var);

VarDeclaration *v = var->isVarDeclaration();
Expand Down
24 changes: 24 additions & 0 deletions test/runnable/testrightthis.d
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,30 @@ class Bar11245
}
}

/********************************************************/
// 11614

struct Tuple11614(T...)
{
T field;
alias field this;
}

struct Foo11614
{
alias Tuple11614!(int) NEW_ARGS;

NEW_ARGS args;

void foo()
{
static if (NEW_ARGS.length == 1)
{}
else
static assert(0);
}
}

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

int main()
Expand Down