Reputation: 3720
I expect the following Rust code to work
struct Expression<'a> {
s: &'a str,
}
impl<'a> Expression<'a> {
fn foo(e: Expression<'a>, _: Expression<'a>) -> Expression<'a> {
e
}
}
fn accept(_: for<'a> fn(Expression<'a>, Expression<'a>) -> Expression<'a>) {
}
fn main() {
accept(Expression::foo)
}
but I get an error message:
error[E0308]: mismatched types
--> src/main.rs:16:12
|
16 | accept(Expression::foo)
| ^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected fn pointer `for<'a> fn(Expression<'a>, Expression<'a>) -> Expression<'a>`
found fn pointer `fn(Expression<'_>, Expression<'_>) -> Expression<'_>`
For more information about this error, try `rustc --explain E0308`.
The error can be fixed by introducing another lifetime 'b
impl<'a> Expression<'a> {
fn foo<'b>(e: Expression<'b>, _: Expression<'b>) -> Expression<'b> {
e
}
}
Can someone explain to me why this is necessary? Isn't 'a
already generic?
Upvotes: 0
Views: 63
Reputation: 70980
Another instance of the late-bound vs. early-bound lifetimes.
A similar problem is in Using HRTBs to automate getter method unit tests. The problem is that while it foo
is generic over 'a
, it is not late-bound but early-bound, meaning that it is fixed when we specify the name of the function and we cannot create a generic function pointer (for<'a>
) from it.
Upvotes: 1