Такое требует кардинальной переделки всего тайпчекера.
В Ди типы распространяются в одном направлении, снизу-вверх.
Если есть вызов функции f(expr), то сперва будет вычислен тип expr, и дальше он будет выбирать нужную перегрузку для f или просто проверяться, что подходит в качестве аргумента f. То, что сама ф-я f ожидает, никак не влияет на тип выражения expr.
Поэтому мы не можем написать
auto fn = (x) => f(x);
даже если тип f известен. Тут тип х явно не указан, компилятор теряется, скомпилить такую лямбду уже не может. И вообще, говорит, в таком виде это еще не функция, а лишь шаблон. Вот применишь его с конкретным типом, тогда приму.
Вот если бы вывод типов был в стиле Хиндли-Милнера, как во многих функциональных языках, то действительно, ожидаемый снаружи тип мог бы диктовать, какой тип должен быть у expr.
Как в нашем SIL:
> f(a, b) => int: if b then a else a*2
> :st f
(integer a, boolean b) -> integer
> g(x,y) => f(y,x)
> :st g
(boolean x, integer y) -> integer
Мы типы для x и y не указываем, но тайпчекер их сам выводит из того, куда они передаются и как используются.
Но в Ди такой способ вывода типов плохо совместим с перегрузками и статической рефлексией. И многие Дивные штуки вроде static if и прочей статической рефлексии нормально работают лишь при одностороннем движении информации о типах, как сейчас. Сделать нормальный вывод типов с двусторонним движением информации и сохранить рефлексию очень сложно, если вообще возможно.