Open
Description
In the following code, identical impls for a concrete type, a fn
type, and a closure exist yet the only the closure fails to meet the higher-ranked bound:
trait FnLt<'a> {
fn apply(self, input: &'a u8) -> &'a u8;
}
// Struct impl
struct Foo;
impl<'a> FnLt<'a> for Foo {
fn apply(self, input: &'a u8) -> &'a u8 {
input
}
}
// Closure impl
impl<'a, T> FnLt<'a> for T
where
T: FnOnce(&'a u8) -> &'a u8,
{
fn apply(self, input: &'a u8) -> &'a u8 {
(self)(input)
}
}
fn take_fn_lt(_: impl for<'a> FnLt<'a>) {}
fn main() {
take_fn_lt(Foo); // Works
fn foo(x: &u8) -> &u8 { x }
take_fn_lt(foo); // Works
take_fn_lt(|x: &u8| -> &u8 { x }); // Doesn't work
}
The error is this:
error[E0271]: type mismatch resolving `for<'a> <[closure@src/main.rs:31:16: 31:37] as std::ops::FnOnce<(&'a u8,)>>::Output == &'a u8`
--> src/main.rs:31:5
|
31 | take_fn_lt(|x: &u8| -> &u8 { x }); // Doesn't work
| ^^^^^^^^^^ expected bound lifetime parameter 'a, found concrete lifetime
|
= note: required because of the requirements on the impl of `for<'a> FnLt<'a>` for `[closure@src/main.rs:31:16: 31:37]`
note: required by `take_fn_lt`
--> src/main.rs:23:1
|
23 | fn take_fn_lt(_: impl for<'a> FnLt<'a>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Edit: the closure can be made to work through coercion to a fn
pointer (which is unsurprising, since it's then the same as foo
). take_fn_lt({ |x: &u8| -> &u8 { x } } as fn(&u8) -> &u8);
compiles.