diff --git a/src/cast.c b/src/cast.c index fc2a7e2df792..b561e86ca419 100644 --- a/src/cast.c +++ b/src/cast.c @@ -1745,15 +1745,18 @@ Expression *CommaExp::castTo(Scope *sc, Type *t) /**************************************** * Set type inference target + * t Target type * flag 1: don't put an error when inference fails + * sc it is used for the semantic of t, when != NULL + * tparams template parameters should be inferred */ -Expression *Expression::inferType(Type *t, int flag, TemplateParameters *tparams) +Expression *Expression::inferType(Type *t, int flag, Scope *sc, TemplateParameters *tparams) { return this; } -Expression *ArrayLiteralExp::inferType(Type *t, int flag, TemplateParameters *tparams) +Expression *ArrayLiteralExp::inferType(Type *t, int flag, Scope *sc, TemplateParameters *tparams) { if (t) { @@ -1764,7 +1767,7 @@ Expression *ArrayLiteralExp::inferType(Type *t, int flag, TemplateParameters *tp for (size_t i = 0; i < elements->dim; i++) { Expression *e = (*elements)[i]; if (e) - { e = e->inferType(tn, flag, tparams); + { e = e->inferType(tn, flag, sc, tparams); (*elements)[i] = e; } } @@ -1773,7 +1776,7 @@ Expression *ArrayLiteralExp::inferType(Type *t, int flag, TemplateParameters *tp return this; } -Expression *AssocArrayLiteralExp::inferType(Type *t, int flag, TemplateParameters *tparams) +Expression *AssocArrayLiteralExp::inferType(Type *t, int flag, Scope *sc, TemplateParameters *tparams) { if (t) { @@ -1785,14 +1788,14 @@ Expression *AssocArrayLiteralExp::inferType(Type *t, int flag, TemplateParameter for (size_t i = 0; i < keys->dim; i++) { Expression *e = (*keys)[i]; if (e) - { e = e->inferType(ti, flag, tparams); + { e = e->inferType(ti, flag, sc, tparams); (*keys)[i] = e; } } for (size_t i = 0; i < values->dim; i++) { Expression *e = (*values)[i]; if (e) - { e = e->inferType(tv, flag, tparams); + { e = e->inferType(tv, flag, sc, tparams); (*values)[i] = e; } } @@ -1801,7 +1804,7 @@ Expression *AssocArrayLiteralExp::inferType(Type *t, int flag, TemplateParameter return this; } -Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams) +Expression *FuncExp::inferType(Type *to, int flag, Scope *sc, TemplateParameters *tparams) { if (!to) return this; @@ -1859,7 +1862,10 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams) Type *tprm = p->type; if (tprm->reliesOnTident(tparams)) goto L1; - tprm = tprm->semantic(loc, td->scope); + if (sc) + tprm = tprm->semantic(loc, sc); + if (tprm->ty == Terror) + goto L1; tiargs->push(tprm); u = dim; // break inner loop } @@ -1915,13 +1921,13 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams) return e; } -Expression *CondExp::inferType(Type *t, int flag, TemplateParameters *tparams) +Expression *CondExp::inferType(Type *t, int flag, Scope *sc, TemplateParameters *tparams) { if (t) { t = t->toBasetype(); - e1 = e1->inferType(t, flag, tparams); - e2 = e2->inferType(t, flag, tparams); + e1 = e1->inferType(t, flag, sc, tparams); + e2 = e2->inferType(t, flag, sc, tparams); } return this; } diff --git a/src/expression.h b/src/expression.h index 5f5d0991799a..52d0e4897c03 100644 --- a/src/expression.h +++ b/src/expression.h @@ -142,7 +142,7 @@ struct Expression : Object virtual MATCH implicitConvTo(Type *t); virtual IntRange getIntRange(); virtual Expression *castTo(Scope *sc, Type *t); - virtual Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); + virtual Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); virtual void checkEscape(); virtual void checkEscapeRef(); virtual Expression *resolveLoc(Loc loc, Scope *sc); @@ -453,7 +453,7 @@ struct ArrayLiteralExp : Expression Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); MATCH implicitConvTo(Type *t); Expression *castTo(Scope *sc, Type *t); - Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); + Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); dt_t **toDt(dt_t **pdt); Expression *doInline(InlineDoState *ids); @@ -479,7 +479,7 @@ struct AssocArrayLiteralExp : Expression Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue); MATCH implicitConvTo(Type *t); Expression *castTo(Scope *sc, Type *t); - Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); + Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); @@ -684,7 +684,7 @@ struct FuncExp : Expression Expression *implicitCastTo(Scope *sc, Type *t); MATCH implicitConvTo(Type *t); Expression *castTo(Scope *sc, Type *t); - Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); + Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); char *toChars(); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); elem *toElem(IRState *irs); @@ -1654,7 +1654,7 @@ struct CondExp : BinExp void toCBuffer(OutBuffer *buf, HdrGenState *hgs); MATCH implicitConvTo(Type *t); Expression *castTo(Scope *sc, Type *t); - Expression *inferType(Type *t, int flag = 0, TemplateParameters *tparams = NULL); + Expression *inferType(Type *t, int flag = 0, Scope *sc = NULL, TemplateParameters *tparams = NULL); Expression *doInline(InlineDoState *ids); Expression *inlineScan(InlineScanState *iss); diff --git a/src/template.c b/src/template.c index 01c0105d0b2e..ace7141c3f16 100644 --- a/src/template.c +++ b/src/template.c @@ -1507,7 +1507,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec if (farg->op == TOKfunction) { FuncExp *fe = (FuncExp *)farg; Type *tp = prmtype; - Expression *e = fe->inferType(tp, 1, parameters); + Expression *e = fe->inferType(tp, 1, paramscope, inferparams); if (!e) goto Lvarargs; farg = e; @@ -1695,7 +1695,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec { FuncExp *fe = (FuncExp *)arg; Type *tp = tb->nextOf(); - Expression *e = fe->inferType(tp, 1, parameters); + Expression *e = fe->inferType(tp, 1, paramscope, inferparams); if (!e) goto Lnomatch; arg = e; diff --git a/test/runnable/funclit.d b/test/runnable/funclit.d index ed092ceff005..4521121e945f 100644 --- a/test/runnable/funclit.d +++ b/test/runnable/funclit.d @@ -716,6 +716,30 @@ void test9153() ]; } +/***************************************************/ +// 9393 + +template ifThrown9393a(E) +{ + void ifThrown9393a(T)(scope T delegate(E) errHandler) + { + } +} +void ifThrown9393b(E, T)(scope T delegate(E) errHandler) +{ +} + +void foo9393(T)(void delegate(T) dg){ dg(T.init); } +void foo9393()(void delegate(int) dg){ foo9393!int(dg); } + +void test9393() +{ + ifThrown9393a!Exception(e => 10); + ifThrown9393b!Exception(e => 10); + + foo9393((x){ assert(x == int.init); }); +} + /***************************************************/ int main() @@ -758,6 +782,7 @@ int main() test8496(); test8575(); test9153(); + test9393(); printf("Success\n"); return 0;