This is similar to something that Lewis Baker presented in the last or last-but-one meeting relating to the mismatch between the capabilities of coroutines and sender/receiver. To apply this change to normal functions seems a stretch, but it isn't a completely crazy thing to do for coroutines, that are already implemented in terms of callbacks on some level and where we already have expectations of a change in semantics. 

Code similar to:

template<class T> void bar(T param);

task<void> foo(variant<int, float> param) {
  auto a = co_await param;

would instantiate bar<int> and bar<float>. The body of foo after the co_await could be seen as being generated as a callback for each type the compiler generates on the return path from co_await. has a section on heterogeneous resume.

So while sender/receiver is focused on async to some extent, you could argue the same of coroutines. Really, though, both of these things are just abstractions of callbacks, much as what you are proposing is. I don't think we see a clear path to making a compiler work for this, though - the way the body of the function would have to be instantiated is a big step from the way templates currently work.