Hi I am new to Rust, I like its elegance but I really could't figure out this. Any help would be appreciated.
Here's the problem: I have a mutable reference of a FnOnce fun
, and I want to apply it. But I will get the error:
error[E0507]: cannot move out of `*fun` which is behind a mutable reference
--> src\future.rs:176:13
|
176 | fun(s).poll()
| ^^^ move occurs because `*fun` has type `Fun`, which does not implement the `Copy` trait
According to the error, I guess it's because application of FnOnce would take its ownership.
Maybe take_mut would be helpful, but it requires to get a value back later; However, after the application, i.e. doing fun(s)
, fun
moved and I could provide a valid value later.
Here's part of the code, I have added the comment at the most important line
pub enum AndThen<Fut1, Fut2, Fun> {
First(Fut1, Fun),
Second(Fut2),
Done,
}
impl<Fut1, Fut2, Fun> Future for AndThen<Fut1, Fut2, Fun>
where
Fut1: Future,
Fut2: Future,
Fun: FnOnce(Fut1::Item) -> Fut2 + Send, //restriction for Fun
{
type Item = Fut2::Item;
fn poll(&mut self) -> Poll<Self::Item> {
match self {
AndThen::First(fut, fun) => { // fun has type Fun, and is a FnOnce
match fut.poll() {
Poll::NotReady => Poll::NotReady,
Poll::Ready(s) => {
fun(s).poll() //need to do application here
}
}
},
AndThen::Second(fut2) => fut2.poll(),
_ => Poll::NotReady
}
}
}
Try for using take_mut as a fix (but it fails since f
moved then I can't provide with a valid return value for take_mut::take)
let mut res = Poll::NotReady;
take_mut::take(fun, |f| {
res = f(s).poll();
f
});
res
Is there a fix other than adding Copy restrictions for Fun?
Thanks!