Extending implicit coercion of function items to function pointers during trait resolution

Haven’t watched through the relevant section fully yet, but if avoiding confusion is the main goal, a diagnostic that suggests adding an as fn(…) -> … cast might be enough. Furthermore, such a diagnostic could be a good first step anyway in evaluating how reliably the compiler can detect cases like this where coercing to a function pointer type makes a trait bound work, and how reliably the right function pointer type can be inferred… etc.


One additional point of confusion is how function types are written. for<'r> fn(&'r [Guess]) -> String {guess} does hardly indicate clearly enough that “this type is not the same as for<'r> fn(&'r [Guess]) -> String”, even though probably half the time you’ll run into this in error messages, it’ll be absolutely crucial for you to understand that you don’t have a function pointer type.

Maybe it should look more like closure types, something like

[function item `guess`: for<'r> fn(&'r [Guess]) -> String]

while we’re at it, closure types could probably benefit from having a visible signature, too, so something like

[closure@src/lib.rs(112:40 - 112:69): for<'r> fn(&'r [Guess]) -> String]

for a non-capturing closure, and something like

[closure@src/lib.rs(112:40 - 112:69): for<'r> Fn(&'r [Guess]) -> String]

or

[closure@src/lib.rs(112:40 - 112:69): for<'r> FnMut(&'r [Guess]) -> String]

or

[closure@src/lib.rs(112:40 - 112:69): for<'r> FnOnce(&'r [Guess]) -> String]

for capturing closures, depending on what the most general function trait they implement is.

6 Likes