Cannot instantiate ReturnType with lambda

Nick Treleaven nick at geany.org
Mon Jul 28 11:18:48 UTC 2025


On Saturday, 26 July 2025 at 23:08:35 UTC, luafyn wrote:
> Why doesn't this work?
>
> ```d
> import std;
>
> struct Optional(T)
> {
>     T value;
>     bool hasValue;
> }
>
> auto map(alias fn, T)(Optional!T m)
> {
>     alias U = ReturnType!fn;

In this case, an untyped function literal (`it => 123`) is 
actually a template function (pointer) and there is no way for 
the compiler to infer what the type of `fn` should be for 
`ReturnType!fn`.

monkyyy's solution is fine, though I'd probably write this:
```d
     alias U = typeof(fn(m.value));
```

>     if (m.hasValue) {
>         return Optional!U(fn(m.value), true);
>     } else {
>         return Optional!U();
>     }
> }
>
> void main()
> {
>     auto x = Optional!string("123", true);
>     auto y = x.map!(it => 123);
>     writeln(y);
> }
> ```
>
> Error:
>
> ```d
> onlineapp.d(11): Error: template instance 
> `onlineapp.main.ReturnType!(__lambda_L23_C21)` does not match 
> template declaration `ReturnType(alias func)`
>   with `func = __lambda_L23_C21(__T1)(it)`
>   must satisfy the following constraint:
> `       isCallable!func`
>     alias U = ReturnType!fn;
>               ^
> onlineapp.d(23): Error: template instance 
> `onlineapp.main.map!((it) => 123, string)` error instantiating
>     auto y = x.map!(it => 123);
>               ^
> ```
>
> This error message makes noooooo sense to me. At all. It's 
> gibberish. How is a lambda not callable?! This is really 
> frustrating, as something that works *absolutely trivially* in 
> any other language.

The problem is `isCallable` (in the general case) cannot detect 
template functions that are instantiable with IFTI. The docs for 
it were updated earlier in the month but are currently only on 
the prerelease version:

https://dlang.org/phobos-prerelease/std_traits.html#isCallable

In Phobos 3 `isCallable` will likely be replaced. I think when it 
was made to support some templates with `!()`, that muddied the 
waters. It would make sense IMO (possibly with another name) if 
it only worked with functions, delegates and types with `opCall`.

Also Steven Schveighoffer [has 
proposed](https://forum.dlang.org/post/dtxmsbsrxtguvyzppamy@forum.dlang.org) `__traits(canCall, expression)` which if implemented would be a much better alternative to using `isCallable` in a template constraint.

> It's something that I've ran against with D time and time 
> again: I get an inscrutable error or problem that is only 
> solved by “just” knowing the right incantation to use, anytime 
> I try to do something even slightly unorthodox, and it makes D 
> really annoying to use if you’re new to it.

It's interesting to see problems like that, there may be ways to 
improve the language/compiler error messages/Phobos or the docs 
to help with these.


More information about the Digitalmars-d-learn mailing list