From ab0d53035222c14c43fecdeb870281e8066a63f7 Mon Sep 17 00:00:00 2001 From: k-hara Date: Tue, 5 Aug 2014 14:04:52 +0900 Subject: [PATCH 1/2] fix Issue 13252 - ParameterDefaultValueTuple affects other instantiations Expression::equals should also compare operand types. --- src/expression.c | 12 ++++++++++-- src/template.c | 17 ++++++++--------- test/runnable/template9.d | 27 +++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/expression.c b/src/expression.c index cb23b42d5f2d..3d6f5ad612db 100644 --- a/src/expression.c +++ b/src/expression.c @@ -3572,8 +3572,11 @@ bool NullExp::equals(RootObject *o) if (o && o->dyncast() == DYNCAST_EXPRESSION) { Expression *e = (Expression *)o; - if (e->op == TOKnull) + if (e->op == TOKnull && + type->toHeadMutable()->equals(e->type->toHeadMutable())) + { return true; + } } return false; } @@ -4022,6 +4025,11 @@ bool ArrayLiteralExp::equals(RootObject *o) ArrayLiteralExp *ae = (ArrayLiteralExp *)o; if (elements->dim != ae->elements->dim) return false; + if (elements->dim == 0 && + !type->toHeadMutable()->equals(ae->type->toHeadMutable())) + { + return false; + } for (size_t i = 0; i < elements->dim; i++) { Expression *e1 = (*elements)[i]; @@ -4273,7 +4281,7 @@ bool StructLiteralExp::equals(RootObject *o) ((Expression *)o)->op == TOKstructliteral) { StructLiteralExp *se = (StructLiteralExp *)o; - if (sd != se->sd) + if (!type->equals(se->type)) return false; if (elements->dim != se->elements->dim) return false; diff --git a/src/template.c b/src/template.c index 063a708d4192..84148173474e 100644 --- a/src/template.c +++ b/src/template.c @@ -292,21 +292,20 @@ int match(RootObject *o1, RootObject *o2) { //printf("t1 = %s\n", t1->toChars()); //printf("t2 = %s\n", t2->toChars()); - if (!t2 || !t1->equals(t2)) + if (!t2) + goto Lnomatch; + if (!t1->equals(t2)) goto Lnomatch; } else if (e1) { -#if 0 - if (e1 && e2) - { - printf("match %d\n", e1->equals(e2)); - printf("\te1 = %p %s %s %s\n", e1, e1->type->toChars(), Token::toChars(e1->op), e1->toChars()); - printf("\te2 = %p %s %s %s\n", e2, e2->type->toChars(), Token::toChars(e2->op), e2->toChars()); - } -#endif if (!e2) goto Lnomatch; +#if 0 + printf("match %d\n", e1->equals(e2)); + printf("\te1 = %p %s %s %s\n", e1, e1->type->toChars(), Token::toChars(e1->op), e1->toChars()); + printf("\te2 = %p %s %s %s\n", e2, e2->type->toChars(), Token::toChars(e2->op), e2->toChars()); +#endif if (!e1->equals(e2)) goto Lnomatch; } diff --git a/test/runnable/template9.d b/test/runnable/template9.d index da2cdc7adb21..7ee0a81a38e0 100644 --- a/test/runnable/template9.d +++ b/test/runnable/template9.d @@ -3854,6 +3854,33 @@ void test13223() //static assert(is(typeof(f5(null)) == void[])); } +/******************************************/ +// 13252 + +alias TypeTuple13252(T...) = T; + +static assert(is(typeof(TypeTuple13252!(cast(int )1)[0]) == int )); +static assert(is(typeof(TypeTuple13252!(cast(long)1)[0]) == long)); + +static assert(is(typeof(TypeTuple13252!(cast(float )3.14)[0]) == float )); +static assert(is(typeof(TypeTuple13252!(cast(double)3.14)[0]) == double)); + +static assert(is(typeof(TypeTuple13252!(cast(cfloat )(1 + 2i))[0]) == cfloat )); +static assert(is(typeof(TypeTuple13252!(cast(cdouble)(1 + 2i))[0]) == cdouble)); + +static assert(is(typeof(TypeTuple13252!(cast(string )null)[0]) == string )); +static assert(is(typeof(TypeTuple13252!(cast(string[])null)[0]) == string[])); // OK <- NG + +static assert(is(typeof(TypeTuple13252!(cast(wstring)"abc")[0]) == wstring)); +static assert(is(typeof(TypeTuple13252!(cast(dstring)"abc")[0]) == dstring)); + +static assert(is(typeof(TypeTuple13252!(cast(int[] )[])[0]) == int[] )); +static assert(is(typeof(TypeTuple13252!(cast(long[])[])[0]) == long[])); // OK <- NG + +struct S13252 { } +static assert(is(typeof(TypeTuple13252!(const S13252())[0]) == const(S13252))); +static assert(is(typeof(TypeTuple13252!(immutable S13252())[0]) == immutable(S13252))); // OK <- NG + /******************************************/ int main() From cf7f48f32fd80e1cfcf35a5d20e02550cf41988a Mon Sep 17 00:00:00 2001 From: k-hara Date: Wed, 6 Aug 2014 00:20:59 +0900 Subject: [PATCH 2/2] Remove toHeadMutable call from NullExp::equals and ArrayLiteralExp::equals I'm not sure we should also remove toHeadMutable call from IntergerExp, RealExp, ComplexExp, and VarExp::equals. To avoid accidental existing code breaking, I'd leave them in 2.066 beta/rc phase. --- src/expression.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/expression.c b/src/expression.c index 3d6f5ad612db..613cdca76251 100644 --- a/src/expression.c +++ b/src/expression.c @@ -3573,7 +3573,7 @@ bool NullExp::equals(RootObject *o) { Expression *e = (Expression *)o; if (e->op == TOKnull && - type->toHeadMutable()->equals(e->type->toHeadMutable())) + type->equals(e->type)) { return true; } @@ -4026,7 +4026,7 @@ bool ArrayLiteralExp::equals(RootObject *o) if (elements->dim != ae->elements->dim) return false; if (elements->dim == 0 && - !type->toHeadMutable()->equals(ae->type->toHeadMutable())) + !type->equals(ae->type)) { return false; }