Comment #0 by snarwin+bugzilla — 2023-11-22T19:35:06Z
As of DMD 2.105.3, the following program fails to compile:
---
void fun(T)(T t, void function(T) f) {}
void main()
{
fun(123, (x) {});
}
---
The error message is:
---
bug.d(5): Error: template `bug.fun` is not callable using argument types `!()(int, void)`
bug.d(1): Candidate is: `fun(T)(T t, void function(T) f)`
---
Since the compiler can deduce that T is int from the argument 123, it should be able to further deduce that the argument (x) {} has type void function(int).
Comment #1 by b2.temp — 2024-09-02T14:07:27Z
Took me a while to get that but I think that in `void function(T)` it's not the same `T` as in `void fun(T)`
Comment #2 by b2.temp — 2024-09-02T14:11:28Z
to be more clear
```
void fun(T)(T t, void function(T) f) {}
void argOK(int){}
void argNG(OtherT)(OtherT ot){}
void main()
{
fun(123, &argOK);
fun(123, &argNG); // semantically equivalent to the original test case
}
```
Comment #3 by snarwin+bugzilla — 2024-09-02T14:33:46Z
Yes, in the current implementation of the DMD frontend, the compiler performs semantic analysis on the argument `(x) {}` *before* it attempts to deduce the template argument `T`, and as a result, it determines that `(x) {}` is template lambda.
However, there is nothing in the language spec that requires the DMD frontend to behave this way. In your example, argNG can *only* be a template, because it is explicitly declared as one. But in the original example, the lambda expression `(x) {}` is ambiguous: it could be a template, or it could be a `void function(int)`.
Given that the language spec gives the compiler the freedom to interpret `(x) {}` either way, I think it's reasonable to request that the compiler choose the more useful interpretation.
Of course, by the same logic, we can't say that the current behavior is *wrong*, so I'll change this to an enhancement request.
Comment #4 by b2.temp — 2024-09-02T16:52:30Z
I agree over the fact that this is an enhancement request.
Comment #5 by robert.schadek — 2024-12-13T19:31:57Z