When I use one of those as a part of complex expression, the one with annotation works well, but for the one without it, the compiler reports an (not very helpful) error of some trait not being implemented.
That trait eventually depends on the closure implementing for<'a> FnOnce(&'a u8) -> Out (for some fixed Out). So I guess the annotation somehow influences the inference of traits implemented by the closure, but I cannot imagine how that can be. The only information the annotation is giving is that the parameter is some reference, but that is also given by the pattern itself.
Lifetime elision (the default relationship between references) in closures works differently than in functions. Closures assume input and output are unrelated, unless something declares otherwise.
This is unfortunately a footgun in the language. Combined with type inference it makes it sensitive to details like this. There isn't any grand design behind this case, it just makes type inference run differently and happens to find the right solution.
The reason this doesn’t Just Work Correctly is because the compiler has to work with much less information than it normally does for a fn signature. I believe that a useful model of what’s going on[1] is that, if you don’t give an explicit type, it's sort of like the closure has been given a signature fn(T) -> U, and the compiler then tries to figure out what particular type T is, separately from its presence in a closure signature, so it can’t introduce a lifetime parameter. In the second case, when you write &_, that's a type with an elided lifetime, so the elision rules introduce a lifetime parameter to the closure.
Practically speaking, you can avoid this problem most of the time by avoiding using a closure expression alone — when the closure is a callback, always pass it immediately to the function that uses it. That way, the function's Fn bound or fn parameter type constrains the closure signature to what is needed. Write this:
This is probably a case of issue #62640. I too got tripped by it recently and spent several hours pulling my hair before accidentally stumbling upon the solution (didn't help that it happened as a part of an ongoing refactor…)