Currently it’s impossible to name the types of standalone functions, methods, and trait-implemented functions. Imagine we have a macro that took the path identifier to a concrete function e.g. type_of_func!(<MyType as Default>::default) and returned the previously unnameable type of the anonymous (opaque) type generated by the compiler.
New powers with this feature:
Send and Sync bounds on all functions. Imagine a components macro you can stick on a function implementation that does some static assert that the type of the function is send plus sync. This would be a cleaner way than constructing a helper generic noop function that asserts its generic parameter is send or sync and then calling this in a test, because it removes the need for the helper function or the test. Now I write this you can do this in a macro anyway, but this style somehow feels cleaner because it talks about the type of the function, rather than ‘at const time’ asserting that the value of the identifyer pointing the function implements some traits.
Intuitive RTN. Since the type outputted by this new macro is, by its name, a function, it must implement FnOnce. Therefore to name the type of the return of the function, you just access FnOnce::Output on the returned type. Simple. Easy. Intuitive. I know no better way of expressing RTN. I’m saying I think this is the best way to implement RTN as a language feature, because it’s not really a language feature specific to solving the specific problem of naming types of only functions returns, it is more of an expansion of the possible programs able to be written which now bestow the power of RTN as a bonus.
This macro should work for traits as well. Take the default trait implemented on some custom type as an example if it helps. You can think of the compiler generating an opaque and now nameable type for each function implementation of a trait, and the traits implementation basically holding an associated type for each function implementation / compiler generated function type. So there is nothing wrong with calling this macro on a trait method of a concrete type
Limitations:
Given some type T that is bounded by some trait, e.g. Default, how do we name the type of the default method in the trait with reference to T? It’s possible for the macro to parse and understand generics, note that this macro would have to be an intrinsic anyway (from my compiler understanding), but would the returned type be generic over T? Yes it would have to be, because different Ts must have different function types for all methods. So it seems possible on first thinking that ‘forwarding’ function types in traits is harmless in generic contexts
I remember reading somewhere that one crate using crater relied on the unnamability of fn types to uphold its safety guarantees, but I would rather break one crate to give the rest this awesome superpower.
Im writing this on iPad on holiday, ill respond and expand this idea with code snippets soon