@@ -684,10 +684,11 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
684684 return protection;
685685 }
686686
687+ import dmd.staticcond;
687688 /* ***************************
688689 * Check to see if constraint is satisfied.
689690 */
690- extern (D ) bool evaluateConstraint(TemplateInstance ti, Scope* sc, Scope* paramscope, Objects* dedargs, FuncDeclaration fd)
691+ extern (D ) StaticConditionResult evaluateConstraint(TemplateInstance ti, Scope* sc, Scope* paramscope, Objects* dedargs, FuncDeclaration fd)
691692 {
692693 /* Detect recursive attempts to instantiate this template declaration,
693694 * https://issues.dlang.org/show_bug.cgi?id=4072
@@ -713,7 +714,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
713714 for (Scope* scx = sc; scx; scx = scx.enclosing)
714715 {
715716 if (scx == p.sc)
716- return false ;
717+ return new StaticConditionResult( null , false , false ) ;
717718 }
718719 }
719720 /* BUG: should also check for ref param differences
@@ -788,13 +789,13 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
788789 ti.inst = ti; // temporary instantiation to enable genIdent()
789790 scx.flags |= SCOPE .constraint;
790791 bool errors;
791- bool result = evalStaticCondition(scx, constraint, e, errors);
792+ auto result = evalStaticCondition(scx, constraint, e, errors);
792793 ti.inst = null ;
793794 ti.symtab = null ;
794795 scx = scx.pop();
795796 previous = pr.prev; // unlink from threaded list
796797 if (errors)
797- return false ;
798+ return new StaticConditionResult( null , false , false ) ;
798799 return result;
799800 }
800801
@@ -833,7 +834,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
833834 * dedtypes deduced arguments
834835 * Return match level.
835836 */
836- extern (D ) MATCH matchWithInstance(Scope* sc, TemplateInstance ti, Objects* dedtypes, Expressions* fargs, int flag)
837+ extern (D ) MatchWithSupplementalInformation matchWithInstance(Scope* sc, TemplateInstance ti, Objects* dedtypes, Expressions* fargs, int flag)
837838 {
838839 enum LOGM = 0 ;
839840 static if (LOGM )
@@ -848,11 +849,12 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
848849 }
849850 MATCH m;
850851 size_t dedtypes_dim = dedtypes.dim;
852+ StaticConditionResult supplementalInformation;
851853
852854 dedtypes.zero();
853855
854856 if (errors)
855- return MATCH .nomatch;
857+ return MatchWithSupplementalInformation ( MATCH .nomatch) ;
856858
857859 size_t parameters_dim = parameters.dim;
858860 int variadic = isVariadic() ! is null ;
@@ -864,7 +866,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
864866 {
865867 printf(" no match: more arguments than parameters\n " );
866868 }
867- return MATCH .nomatch;
869+ return MatchWithSupplementalInformation ( MATCH .nomatch) ;
868870 }
869871
870872 assert (dedtypes_dim == parameters_dim);
@@ -970,7 +972,8 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
970972 }
971973
972974 // TODO: dedtypes => ti.tiargs ?
973- if (! evaluateConstraint(ti, sc, paramscope, dedtypes, fd))
975+ supplementalInformation = evaluateConstraint(ti, sc, paramscope, dedtypes, fd);
976+ if (! supplementalInformation.result)
974977 goto Lnomatch;
975978 }
976979
@@ -1016,7 +1019,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
10161019 {
10171020 printf(" -TemplateDeclaration.matchWithInstance(this = %p, ti = %p) = %d\n " , this , ti, m);
10181021 }
1019- return m ;
1022+ return MatchWithSupplementalInformation (m) ;
10201023 }
10211024
10221025 /* *******************************************
@@ -1025,7 +1028,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
10251028 * match this is at least as specialized as td2
10261029 * 0 td2 is more specialized than this
10271030 */
1028- MATCH leastAsSpecialized (Scope* sc, TemplateDeclaration td2, Expressions* fargs)
1031+ MatchWithSupplementalInformation leastAsSpecialized (Scope* sc, TemplateDeclaration td2, Expressions* fargs)
10291032 {
10301033 enum LOG_LEASTAS = 0 ;
10311034 static if (LOG_LEASTAS )
@@ -1061,8 +1064,8 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
10611064 Objects dedtypes = Objects(td2.parameters.dim);
10621065
10631066 // Attempt a type deduction
1064- MATCH m = td2.matchWithInstance(sc, ti, &dedtypes, fargs, 1 );
1065- if (m > MATCH .nomatch)
1067+ auto m = td2.matchWithInstance(sc, ti, &dedtypes, fargs, 1 );
1068+ if (m.match > MATCH .nomatch)
10661069 {
10671070 /* A non-variadic template is more specialized than a
10681071 * variadic one.
@@ -1082,7 +1085,12 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
10821085 {
10831086 printf(" doesn't match, so is not as specialized\n " );
10841087 }
1085- return MATCH .nomatch;
1088+ return MatchWithSupplementalInformation (MATCH .nomatch);
1089+ }
1090+
1091+ struct MatchWithSupplementalInformation {
1092+ MATCH match;
1093+ StaticConditionResult supplementalInformation;
10861094 }
10871095
10881096 /* ************************************************
@@ -1101,13 +1109,14 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
11011109 * bit 0-3 Match template parameters by inferred template arguments
11021110 * bit 4-7 Match template parameters by initial template arguments
11031111 */
1104- extern (D ) MATCH deduceFunctionTemplateMatch(TemplateInstance ti, Scope* sc, ref FuncDeclaration fd, Type tthis, Expressions* fargs)
1112+ extern (D ) MatchWithSupplementalInformation deduceFunctionTemplateMatch(TemplateInstance ti, Scope* sc, ref FuncDeclaration fd, Type tthis, Expressions* fargs)
11051113 {
11061114 size_t nfparams;
11071115 size_t nfargs;
11081116 size_t ntargs; // array size of tiargs
11091117 size_t fptupindex = IDX_NOTFOUND ;
11101118 MATCH match = MATCH .exact;
1119+ StaticConditionResult supplementalInformation;
11111120 MATCH matchTiargs = MATCH .exact;
11121121 ParameterList fparameters; // function parameter list
11131122 VarArg fvarargs; // function varargs
@@ -1142,7 +1151,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
11421151 dedtypes.zero();
11431152
11441153 if (errors || fd.errors)
1145- return MATCH .nomatch;
1154+ return MatchWithSupplementalInformation ( MATCH .nomatch) ;
11461155
11471156 // Set up scope for parameters
11481157 Scope* paramscope = scopeForTemplateParameters(ti,sc);
@@ -2003,8 +2012,11 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
20032012
20042013 if (constraint)
20052014 {
2006- if (! evaluateConstraint(ti, sc, paramscope, dedargs, fd))
2015+ supplementalInformation = evaluateConstraint(ti, sc, paramscope, dedargs, fd);
2016+ if (! supplementalInformation.result)
2017+ {
20072018 goto Lnomatch;
2019+ }
20082020 }
20092021
20102022 version (none )
@@ -2018,18 +2030,18 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
20182030
20192031 paramscope.pop();
20202032 // printf("\tmatch %d\n", match);
2021- return cast (MATCH )(match | (matchTiargs << 4 ));
2033+ return MatchWithSupplementalInformation ( cast (MATCH )(match | (matchTiargs << 4 ) ));
20222034
20232035 Lnomatch:
20242036 paramscope.pop();
20252037 // printf("\tnomatch\n");
2026- return MATCH .nomatch;
2038+ return MatchWithSupplementalInformation ( MATCH .nomatch, supplementalInformation) ;
20272039
20282040 Lerror:
20292041 // todo: for the future improvement
20302042 paramscope.pop();
20312043 // printf("\terror\n");
2032- return MATCH .nomatch;
2044+ return MatchWithSupplementalInformation ( MATCH .nomatch) ;
20332045 }
20342046
20352047 /* *************************************************
@@ -2592,10 +2604,14 @@ void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiar
25922604 auto ti = new TemplateInstance(loc, td, tiargs);
25932605 Objects dedtypes = Objects(td.parameters.dim);
25942606 assert (td.semanticRun != PASS .init);
2595- MATCH mta = td.matchWithInstance(sc, ti, &dedtypes, fargs, 0 );
2607+ auto mta = td.matchWithInstance(sc, ti, &dedtypes, fargs, 0 );
25962608 // printf("matchWithInstance = %d\n", mta);
2597- if (mta <= MATCH .nomatch || mta < ta_last) // no match or less match
2609+ if (mta.match <= MATCH .nomatch || mta.match < ta_last) // no match or less match
2610+ {
2611+ if (pMessage && mta.supplementalInformation)
2612+ * pMessage = mta.supplementalInformation.toChars();
25982613 return 0 ;
2614+ }
25992615
26002616 ti.templateInstanceSemantic(sc, fargs);
26012617 if (! ti.inst) // if template failed to expand
@@ -2665,8 +2681,8 @@ void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiar
26652681 if (mfa < m.last)
26662682 return 0 ;
26672683
2668- if (mta < ta_last) goto Ltd_best2;
2669- if (mta > ta_last) goto Ltd2;
2684+ if (mta.match < ta_last) goto Ltd_best2;
2685+ if (mta.match > ta_last) goto Ltd2;
26702686
26712687 if (mfa < m.last) goto Ltd_best2;
26722688 if (mfa > m.last) goto Ltd2;
@@ -2686,7 +2702,7 @@ void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiar
26862702 td_best = td;
26872703 ti_best = null ;
26882704 property = 0 ; // (backward compatibility)
2689- ta_last = mta;
2705+ ta_last = mta.match ;
26902706 m.last = mfa;
26912707 m.lastf = fd;
26922708 tthis_best = tthis_fd;
@@ -2708,12 +2724,17 @@ void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiar
27082724 ti.parent = td.parent; // Maybe calculating valid 'enclosing' is unnecessary.
27092725
27102726 auto fd = f;
2711- int x = td.deduceFunctionTemplateMatch(ti, sc, fd, tthis, fargs);
2727+ auto information = td.deduceFunctionTemplateMatch(ti, sc, fd, tthis, fargs);
2728+ int x = information.match;
27122729 MATCH mta = cast (MATCH )(x >> 4 );
27132730 MATCH mfa = cast (MATCH )(x & 0xF );
27142731 // printf("match:t/f = %d/%d\n", mta, mfa);
27152732 if (! fd || mfa == MATCH .nomatch)
2733+ {
2734+ if (pMessage && information.supplementalInformation)
2735+ * pMessage = information.supplementalInformation.toChars();
27162736 continue ;
2737+ }
27172738
27182739 Type tthis_fd = fd.needThis() ? tthis : null ;
27192740
@@ -2743,8 +2764,8 @@ void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiar
27432764 if (td_best)
27442765 {
27452766 // Disambiguate by picking the most specialized TemplateDeclaration
2746- MATCH c1 = td.leastAsSpecialized(sc, td_best, fargs);
2747- MATCH c2 = td_best.leastAsSpecialized(sc, td, fargs);
2767+ MATCH c1 = td.leastAsSpecialized(sc, td_best, fargs).match ;
2768+ MATCH c2 = td_best.leastAsSpecialized(sc, td, fargs).match ;
27482769 // printf("1: c1 = %d, c2 = %d\n", c1, c2);
27492770 if (c1 > c2) goto Ltd;
27502771 if (c1 < c2) goto Ltd_best;
@@ -6897,7 +6918,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
68976918 assert (tempdecl._scope);
68986919 // Deduce tdtypes
68996920 tdtypes.setDim(tempdecl.parameters.dim);
6900- if (! tempdecl.matchWithInstance(sc, this , &tdtypes, fargs, 2 ))
6921+ if (! tempdecl.matchWithInstance(sc, this , &tdtypes, fargs, 2 ).match )
69016922 {
69026923 error(" incompatible arguments for template instantiation" );
69036924 return false ;
@@ -6952,7 +6973,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
69526973 dedtypes.zero();
69536974 assert (td.semanticRun != PASS .init);
69546975
6955- MATCH m = td.matchWithInstance(sc, this , &dedtypes, fargs, 0 );
6976+ MATCH m = td.matchWithInstance(sc, this , &dedtypes, fargs, 0 ).match ;
69566977 // printf("matchWithInstance = %d\n", m);
69576978 if (m <= MATCH .nomatch) // no match at all
69586979 return 0 ;
@@ -6961,8 +6982,8 @@ extern (C++) class TemplateInstance : ScopeDsymbol
69616982
69626983 // Disambiguate by picking the most specialized TemplateDeclaration
69636984 {
6964- MATCH c1 = td.leastAsSpecialized(sc, td_best, fargs);
6965- MATCH c2 = td_best.leastAsSpecialized(sc, td, fargs);
6985+ MATCH c1 = td.leastAsSpecialized(sc, td_best, fargs).match ;
6986+ MATCH c2 = td_best.leastAsSpecialized(sc, td, fargs).match ;
69666987 // printf("c1 = %d, c2 = %d\n", c1, c2);
69676988 if (c1 > c2) goto Ltd;
69686989 if (c1 < c2) goto Ltd_best;
@@ -7182,7 +7203,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
71827203 return 1 ;
71837204 }
71847205 }
7185- MATCH m = td.matchWithInstance(sc, this , &dedtypes, null , 0 );
7206+ MATCH m = td.matchWithInstance(sc, this , &dedtypes, null , 0 ).match ;
71867207 if (m <= MATCH .nomatch)
71877208 return 0 ;
71887209 }
0 commit comments