Skip to content

Commit 520984b

Browse files
committed
Initial Thought
1 parent 6476ceb commit 520984b

File tree

2 files changed

+108
-4
lines changed

2 files changed

+108
-4
lines changed

compiler/src/dmd/funcsem.d

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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
15301528
FuncDeclaration 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
{
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
TEST_OUTPUT:
3+
---
4+
fail_compilation/test_missing_template_parameter.d(23): Error: template `test2` is not callable using argument types `!()(uint)`
5+
fail_compilation/test_missing_template_parameter.d(23): missing argument for template parameter #1: `C`
6+
fail_compilation/test_missing_template_parameter.d(15): Candidate is: `test2(C)(uint id)`
7+
---
8+
*/
9+
10+
void test1(uint id, uint __)
11+
{
12+
int x = 0;
13+
}
14+
15+
void test2(C)(uint id)
16+
{
17+
int x = 0;
18+
}
19+
20+
void main()
21+
{
22+
uint a = 0;
23+
test2(a);
24+
}

0 commit comments

Comments
 (0)