Description
Consider this code:
#![feature(unboxed_closures)]
fn foo<F>(f: F) where
for<'a> F: FnOnce<&'a i32>,
for<'a> <F as FnOnce<&'a i32>>::Output: Iterator<Item=&'a i64> {}
The bound is intended to match functions roughly of the form
fn callback<'a>(x: &'a i32) -> impl Iterator<Item=&'a i64> { ... }
However, rustc rejects foo
with this error:
error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
--> src/lib.rs:4:54
|
4 | for<'a> <F as FnOnce<&'a i32>>::Output: Iterator<Item=&'a i64> {}
| ^^^^^^^^^^^^
The rustc --explain
output points to issue #33685, which had to do with declarations where a lifetime appeared in a function's return type and nowhere else, like:
fn foo<'a>() -> &'a u32 { .. }
In that issue, @nikomatsakis wrote:
These constructs are being rejected as part of the fix for issue #32330. This is a soundness bug that concerns cases like these.
[..]
These sorts of where-clauses and types are not only ill-formed, they are useless. For example, now that #32330 is fixed, there are no types that could satisfy such a where-clause, nor are there any functions with a type likefor<'a> fn() -> &'a i32
(see next section for more details).
[..]
The crux of the problem concerns lifetime parameters that only appear in the return type of a fn declaration -- these are changing to no longer be considered "higher-ranked" (or "late-bound").
My example is different, though, in that the lifetime does appear in the function's arguments. Thus, while I don't know whether allowing the bound would implicate the same soundness issue, I'm pretty sure the bound is not useless: it seems like it should be possible to satisfy.