If I try to implement the trait Frob
for functions like foo
as follows:
fn foo<'b>(state: &'b mut i32) -> impl FnMut(&str) -> i32 + 'b {
move |i| *state
}
trait Frob<S, I, O> {
fn frob(self, state: &mut S, input: I) -> O;
}
impl<S, I, O, F, G> Frob<S, I, O> for F
where
F: FnMut(&mut S) -> G,
G: FnMut(I) -> O,
{
fn frob(mut self, state: &mut S, input: I) -> O {
self(state)(input)
}
}
fn bar() {
foo.frob(&mut 1, "hi");
}
I get the error
error[E0599]: the method `frob` exists for fn item `for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}`,
but its trait bounds were not satisfied
...
= note: the following trait bounds were not satisfied:
`<for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo} as FnOnce<(&mut _,)>>::Output = _`
which is required by `for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}: Frob<_, _, _>`
`<&for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo} as FnOnce<(&mut _,)>>::Output = _`
which is required by `&for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}: Frob<_, _, _>`
`<&mut for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo} as FnOnce<(&mut _,)>>::Output = _`
which is required by `&mut for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}: Frob<_, _, _>`
First of all, how do I interpret this error message? Second, how do I write the trait bound correctly? Presumably the problem has something to do with the returned closure hanging on to state
, but I can't find a place to specify a lifetime for G
.
First of all, how do I interpret this error message?
Yes, it is a tad cryptic isn't it? Two things to recognise:
<for<'b> fn(&'b mut i32) -> impl for<'b, 'r> FnMut<(&'r str,)> {foo}
is the compiler's very wordy way of expressing the type of function foo
; and
the same note is repeated for that function type, a shared reference to that function type, and a mutable reference to that function type—this happens when the compiler attempts automatic referencing in method call syntax such as you have in foo.frob(...)
.
So we can quickly distill the error message down to:
error[E0599]: the method `frob` exists for fn item `{foo}`, but its trait bounds were not satisfied ... = note: the following trait bounds were not satisfied: `<{foo} as FnOnce<(&mut _,)>>::Output = _` which is required by `{foo}: Frob<_, _, _>`
The compiler is telling us that it found a potential frob
method on {foo}
but in order for it to be applicable, {foo}
's return type must match the constraints of the Frob
trait (but it doesn't).
Second, how do I write the trait bound correctly? Presumably the problem has something to do with the returned closure hanging on to
state
, but I can't find a place to specify a lifetime forG
.
You need to add the lifetime constraint to the trait ( playground ):
trait Frob<'b, S, I, O> { fn frob(self, state: &'b mut S, input: I) -> O; } impl<'b, S: 'b, I, O, F, G> Frob<'b, S, I, O> for F where F: FnMut(&'b mut S) -> G, G: 'b + FnMut(I) -> O, { fn frob(mut self, state: &'b mut S, input: I) -> O { self(state)(input) } }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.