-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsC-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
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.
Metadata
Metadata
Assignees
Labels
A-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsC-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.