@@ -323,12 +323,10 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl)
323323 * auto bar() {} // become a weak purity function
324324 * class C { // nested class
325325 * auto baz() {} // become a weak purity function
326- * }
327326 *
328327 * static auto boo() {} // typed as impure
329328 * // Even though, boo cannot call any impure functions.
330329 * // See also Expression::checkPurity().
331- * }
332330 */
333331 if (tf.purity == PURE .impure && (funcdecl.isNested() || funcdecl.isThis()))
334332 {
@@ -1530,7 +1528,7 @@ enum FuncResolveFlag : ubyte
15301528FuncDeclaration resolveFuncCall (Loc loc, Scope* sc, Dsymbol s,
15311529 Objects* tiargs, Type tthis, ArgumentList argumentList, FuncResolveFlag flags)
15321530{
1533- // printf("resolveFuncCall() %s\n", s.toChars());
1531+ // printf("resolveFuncCall() %s) \n", s.toChars());
15341532 auto fargs = argumentList.arguments;
15351533 if (! s)
15361534 return null ; // no match
@@ -1658,15 +1656,47 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
16581656 {
16591657 .error(loc, " %s `%s` is not callable using argument types `!(%s)%s`" ,
16601658 td.kind(), td.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
1659+
1660+ // Check for missing template parameters
1661+ if (tiargs == null || tiargs.length == 0 )
1662+ {
1663+ foreach (i, param; * (td.parameters))
1664+ {
1665+ if (! param.isTemplateTupleParameter() && ! param.hasDefaultArg())
1666+ {
1667+ .errorSupplemental(loc, " missing argument for template parameter #%d: `%s`" ,
1668+ cast (int )(i + 1 ), param.ident.toChars());
1669+ break ; // Show just the first missing parameter to avoid cluttering the output
1670+ }
1671+ }
1672+ }
16611673 }
16621674 else
16631675 {
16641676 .error(loc, " none of the overloads of %s `%s.%s` are callable using argument types `!(%s)%s`" ,
16651677 td.kind(), td.parent.toPrettyChars(), td.ident.toChars(),
16661678 tiargsBuf.peekChars(), fargsBuf.peekChars());
1679+
1680+ // Check for missing template parameters in the most likely candidate
1681+ if (tiargs == null || tiargs.length == 0 )
1682+ {
1683+ // Identify the most likely candidate from the overload set
1684+ TemplateDeclaration candidate = td;
1685+ if (candidate && candidate.parameters && candidate.parameters.length > 0 )
1686+ {
1687+ foreach (i, param; * (candidate.parameters))
1688+ {
1689+ if (! param.isTemplateTupleParameter() && ! param.hasDefaultArg())
1690+ {
1691+ .errorSupplemental(loc, " missing argument for template parameter #%d: `%s`" ,
1692+ cast (int )(i + 1 ), param.ident.toChars());
1693+ break ; // Just the first missing parameter
1694+ }
1695+ }
1696+ }
1697+ }
16671698 }
16681699
1669-
16701700 if (! global.gag || global.params.v.showGaggedErrors)
16711701 printCandidates(loc, td, sc.isDeprecated());
16721702 return null ;
@@ -1684,6 +1714,37 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
16841714 {
16851715 .error(loc, " none of the overloads of `%s` are callable using argument types `!(%s)%s`" ,
16861716 od.ident.toChars(), tiargsBuf.peekChars(), fargsBuf.peekChars());
1717+
1718+ // Check for missing template parameters in overload declaration candidates
1719+ if (tiargs == null || tiargs.length == 0 )
1720+ {
1721+ // Try to find a template declaration from the overload set
1722+ bool found = false ;
1723+ overloadApply(od, (Dsymbol s)
1724+ {
1725+ if (found)
1726+ return 0 ;
1727+
1728+ if (auto td = s.isTemplateDeclaration())
1729+ {
1730+ if (td.parameters && td.parameters.length > 0 )
1731+ {
1732+ foreach (i, param; * (td.parameters))
1733+ {
1734+ if (! param.isTemplateTupleParameter() && ! param.hasDefaultArg())
1735+ {
1736+ .errorSupplemental(loc, " missing argument for template parameter #%d: `%s`" ,
1737+ cast (int )(i + 1 ), param.ident.toChars());
1738+ found = true ;
1739+ break ;
1740+ }
1741+ }
1742+ }
1743+ }
1744+ return 0 ;
1745+ });
1746+ }
1747+
16871748 if (! global.gag || global.params.v.showGaggedErrors)
16881749 printCandidates(loc, od, sc.isDeprecated());
16891750 return null ;
@@ -1792,6 +1853,25 @@ FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s,
17921853 }
17931854 }
17941855 }
1856+
1857+ // Check if this is a template function with no template arguments provided
1858+ if (fd.parent && fd.parent.isTemplateDeclaration())
1859+ {
1860+ auto parentTd = fd.parent.isTemplateDeclaration();
1861+ if (parentTd && parentTd.parameters && parentTd.parameters.length > 0 && (tiargs == null || tiargs.length == 0 ))
1862+ {
1863+ // Look for missing template parameters
1864+ foreach (i, param; * (parentTd.parameters))
1865+ {
1866+ if (! param.isTemplateTupleParameter() && ! param.hasDefaultArg())
1867+ {
1868+ .errorSupplemental(loc, " missing argument for template parameter #%d: `%s`" ,
1869+ cast (int )(i + 1 ), param.ident.toChars());
1870+ break ;
1871+ }
1872+ }
1873+ }
1874+ }
17951875
17961876 void errorHelper2 (const (char )* failMessage) scope
17971877 {
0 commit comments