From a58b3735f6a5cf071605e6f2606e7f1be3d6c38f Mon Sep 17 00:00:00 2001 From: k-hara Date: Thu, 16 Jan 2014 02:39:15 +0900 Subject: [PATCH] Issue 11930 - Alias this not considered in is(T unused: U) matching --- src/mtype.h | 2 -- src/template.c | 63 +++++++++++++-------------------------- test/runnable/aliasthis.d | 47 ++++++++++++++++++++--------- 3 files changed, 53 insertions(+), 59 deletions(-) diff --git a/src/mtype.h b/src/mtype.h index 37ee2f254123..835b1c174757 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -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(); @@ -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(); diff --git a/src/template.c b/src/template.c index 8dc114a28d03..bfb7fb30747a 100644 --- a/src/template.c +++ b/src/template.c @@ -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; } @@ -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(); @@ -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()); diff --git a/test/runnable/aliasthis.d b/test/runnable/aliasthis.d index b8aec2c72c10..329076785e11 100644 --- a/test/runnable/aliasthis.d +++ b/test/runnable/aliasthis.d @@ -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