Mixin template parameter overloading bug?

Steven Schveighoffer schveiguy at gmail.com
Sat Jun 14 23:49:19 UTC 2025


On Saturday, 14 June 2025 at 00:02:32 UTC, Andrey Zherikov wrote:
> The simplest code that shows the issue:
> ```d
> struct S{}
>
> template f(void function(S) F) {}
> template f(int function(S) F) {}
>
> mixin f!((_) {});
> mixin f!((_) => 0);  // Error: cannot return non-void from 
> `void` function
>                      // mixin f!((_) => 0);
>                      //                 ^
>                      //        while looking for match for 
> `f!((_) => 0)`
>                      // mixin f!((_) => 0);
> ```
>
> If I swap `template f` declarations:
> ```d
> struct S{}
>
> template f(int function(S) F) {}
> template f(void function(S) F) {}
>
> mixin f!((_) {}); // Error: function 
> `onlineapp.__lambda_L8_C10(__T1)(_)` has no `return` statement, 
> but is expected to return a value of type `int`
>                   // mixin f!((_) {});
>                   //          ^
>                   //         while looking for match for `f!((_)
>                   // {
>                   // }
>                   // )`
>                   // mixin f!((_) {});
>                   // ^
> mixin f!((_) => 0);
> ```
>
> But if I remove `S` from template parameters, everything works:
> ```d
> template f(int function() F) {}
> template f(void function() F) {}
>
> mixin f!(() {});
> mixin f!(() => 0);
> ```
>
> Is this a bug somewhere in compiler or in my code?

A lambda is a shortened syntax for a function literal or delegate 
literal.

HOWEVER, when you do not give the parameters types, the lambda 
becomes a template! Well, not actually a template, but a 
quasi-template.

If you add types to your lambda, then the compiler can figure it 
out:

```d
mixin f!((S _) {});
mixin f!((S _) => 0);
```

These are now no longer templates, but instead concrete function 
literals.

BIG NOTE: just putting `S` doesn't work, because `S` becomes the 
parameter name in that case. This is why `int` might work there 
-- `int` cannot be a parameter name.

If I had to guess, I think the compiler is not able to exactly 
deduce what form your lambda should be instantiated with. I think 
it's picking the first form it sees.

I think if anything, the error message is really weird. I'd 
expect possibly an ambiguity error. But I'm not sure the language 
is supposed to handle your case.

-Steve


More information about the Digitalmars-d-learn mailing list