Skip to content

Commit

Permalink
Issue 11930 - Alias this not considered in is(T unused: U) matching
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Jan 15, 2014
1 parent 786ea82 commit a58b373
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 59 deletions.
2 changes: 0 additions & 2 deletions src/mtype.h
Expand Up @@ -851,7 +851,6 @@ class TypeStruct : public Type
bool needsNested();
dt_t **toDt(dt_t **pdt);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm = NULL);
MATCH deduceTypeNoRecursion(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm);
TypeInfoDeclaration *getTypeInfoDeclaration();
int hasPointers();
TypeTuple *toArgTypes();
Expand Down Expand Up @@ -981,7 +980,6 @@ class TypeClass : public Type
Expression *defaultInit(Loc loc);
int isZeroInit(Loc loc);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm = NULL);
MATCH deduceTypeNoRecursion(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm);
int isscope();
int checkBoolean();
TypeInfoDeclaration *getTypeInfoDeclaration();
Expand Down
63 changes: 20 additions & 43 deletions src/template.c
Expand Up @@ -3389,9 +3389,26 @@ MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
MATCH m = implicitConvTo(tparam);
if (m == MATCHnomatch)
{
Type *at = aliasthisOf();
if (at)
m = at->deduceType(sc, tparam, parameters, dedtypes, wm);
if (ty == Tclass)
{
TypeClass *tc = (TypeClass *)this;
if (tc->sym->aliasthis && !(tc->att & RECtracingDT))
{
tc->att = (AliasThisRec)(tc->att | RECtracingDT);
m = aliasthisOf()->deduceType(sc, tparam, parameters, dedtypes, wm);
tc->att = (AliasThisRec)(tc->att & ~RECtracingDT);
}
}
else if (ty == Tstruct)
{
TypeStruct *ts = (TypeStruct *)this;
if (ts->sym->aliasthis && !(ts->att & RECtracingDT))
{
ts->att = (AliasThisRec)(ts->att | RECtracingDT);
m = aliasthisOf()->deduceType(sc, tparam, parameters, dedtypes, wm);
ts->att = (AliasThisRec)(ts->att & ~RECtracingDT);
}
}
}
return m;
}
Expand Down Expand Up @@ -3875,26 +3892,6 @@ MATCH TypeInstance::deduceType(Scope *sc,
}

MATCH TypeStruct::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm)
{
MATCH m;
if (sym->aliasthis)
{
if (att & RECtracingDT)
m = MATCHnomatch;
else
{
att = (AliasThisRec)(att | RECtracingDT);
m = deduceTypeNoRecursion(sc, tparam, parameters, dedtypes, wm);
att = (AliasThisRec)(att & ~RECtracingDT);
}
}
else
m = deduceTypeNoRecursion(sc, tparam, parameters, dedtypes, wm);

return m;
}

MATCH TypeStruct::deduceTypeNoRecursion(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm)
{
//printf("TypeStruct::deduceType()\n");
//printf("\tthis->parent = %s, ", sym->parent->toChars()); print();
Expand Down Expand Up @@ -4040,26 +4037,6 @@ void deduceBaseClassParameters(BaseClass *b,
}

MATCH TypeClass::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm)
{
MATCH m;
if (sym->aliasthis)
{
if (att & RECtracingDT)
m = MATCHnomatch;
else
{
att = (AliasThisRec)(att | RECtracingDT);
m = deduceTypeNoRecursion(sc, tparam, parameters, dedtypes, wm);
att = (AliasThisRec)(att & ~RECtracingDT);
}
}
else
m = deduceTypeNoRecursion(sc, tparam, parameters, dedtypes, wm);

return m;
}

MATCH TypeClass::deduceTypeNoRecursion(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wm)
{
//printf("TypeClass::deduceType(this = %s)\n", toChars());

Expand Down
47 changes: 33 additions & 14 deletions test/runnable/aliasthis.d
Expand Up @@ -407,30 +407,49 @@ void test7()
/***************************************************/
// 11875 - endless recursion in Type::deduceType

struct T1(C)
struct T11875x(C)
{
C c;
}

class D1 { D2 c; alias c this; }
class D2 { D1 c; alias c this; }

static assert(!is(D1 == D2));
static if(is(T1!D1 == T1!D, D))
static assert(is(D == D1));
static if(is(D1 == T1!D, D)) // this used to freeze dmd
static assert(false);
class D11875a { D11875b c; alias c this; }
class D11875b { D11875a c; alias c this; }
static assert(!is(D11875a == D11875b));
static assert( is(T11875x!D11875a == T11875x!D, D) && is(D == D11875a));
static assert(!is(D11875a == T11875x!D, D)); // this used to freeze dmd

// test that types in recursion are still detected
class D3 { T2!D2 c; alias c this; }

struct T2(C)
struct T11875y(C)
{
C c;
alias c this;
}
static assert(is(D3 : T2!D, D) && is(D == D2));
class D11875c { T11875y!D11875b c; alias c this; }
static assert(is(D11875c : T11875y!D, D) && is(D == D11875b));

/***************************************************/
// 11930

class BarObj11930 {}

struct Bar11930
{
BarObj11930 _obj;
alias _obj this;
}

BarObj11930 getBarObj11930(T)(T t)
{
static if (is(T unused : BarObj11930))
return t;
else
static assert(false, "Can not get BarObj from " ~ T.stringof);
}

void test11930()
{
Bar11930 b;
getBarObj11930(b);
}

/***************************************************/
// 2781
Expand Down

0 comments on commit a58b373

Please sign in to comment.