It fails to compile because compiler cannot deduce the type of buf anymore:
error[E0282]: type annotations needed
--> src/lib.rs:7:24
|
7 | set_callback(Some(|buf| buf[0] = 0));
| ^^^ consider giving this closure parameter a type
|
= note: type must be known at this point
For more information about this error, try `rustc --explain E0282`.
error: could not compile `playground` due to previous error
What is really happening when compiler tries to deduce the types of closure parameters? Is it unsound to deduce the type of buf to &mut [u8] when the closure is wrapped in something like Option?
"The type inference is based on the standard Hindley-Milner (HM) type inference algorithm, but extended in various way to accommodate subtyping, region inference, and higher-ranked types."
This type of inference failure seems to commonly happen when the type is needed to call a method or similar, and that context doesn't constrain the closure well enough. In this case, the type is needed to know what type of Option<T> to instantiate. It's not a soundness issue.
You could have a
fn set_callback_to<F>(f: F)
where
F: FnOnce(&mut [u8])
{
set_callback(Some(f))
}
to work around it. (Or a free function fn(F) -> Option<F>.)
Also, for this particular example, note that you can't pass None and have things work either. That would be true whatever the bounds on Option<SomeGenericParameter>, but you can't name closure types, so you can't annotate the None to instantiate F to be a closure type. And if you're storing a callback, you're probably boxing it up within your struct anyway, so perhaps have a method that takes a Option<Box<dyn FnOnce(...)>>.
It's way beyond my knowledge and understanding to give you a definitive answer, but my very vague, fuzzy understanding would be that when you get into areas like closures, function pointers and enums where there could be any number of potential matches, you are reaching the limits of reasonable type inference. I doubt this is a bug or anything, sometimes in these areas you simply DO have to supply more type information. There might be some RFC proposal to change this, but I somewhat doubt it. Perhaps an expert can explain more clearly ( I am not one on this subject ).
This is probably considered part of #12679. In a different inference bug, ExpHp says:
the compiler has a special case when type checking closures that appear as function arguments (it will infer types from Fn bounds). So this problem (and many other related problems with type inference) tends to rear its ugly head only in comparatively uncommon scenarios, such as when assigning a closure to a local variable with let .
As far as I know there's nothing blocking a PR other than the difficulty of writing it (but I, too, am not an expert on compiler internals). That issue is almost 8 years old and predates stable Rust.