I have use_future
and it takes impl FnMut() -> F + 'static
. With the move || async move {}
as the closure, I don't have a good way to deal with the move.
#![deny(elided_lifetimes_in_paths)]
#![allow(unused_variables)]
// mimic https://docs.rs/dioxus-hooks/latest/dioxus_hooks/fn.use_future.html
fn use_future<F>(_future: impl FnMut() -> F + 'static)
where
F: std::future::Future + 'static,
{
()
}
#[derive(Clone)]
struct Props {
id: String,
x: Vec<i64>,
y: Vec<i64>,
}
fn component(props: Props) {
use_future(move || async move {
let plot = Plot::new(Bar::new(props.x, props.y));
new_plot(&props.id, &plot).await;
});
// I am still in use in the HTML later
let _ = &props;
}
struct Plot {
bar: Bar,
}
impl Plot {
fn new(bar: Bar) -> Self {
Self { bar }
}
}
struct Bar {
x: Vec<i64>,
y: Vec<i64>,
}
impl Bar {
fn new(x: Vec<i64>, y: Vec<i64>) -> Self {
Self { x, y }
}
}
async fn new_plot(id: &str, plot: &Plot) {
todo!()
}
error[E0507]: cannot move out of `props.id`, a captured variable in an `FnMut` closure
--> src/lib.rs:20:24
|
19 | fn component(props: Props) {
| ----- captured outer variable
20 | use_future(move || async move {
| ________________-------_^
| | |
| | captured by this `FnMut` closure
21 | | let plot = Plot::new(Bar::new(props.x, props.y));
22 | |
23 | | new_plot(&props.id, &plot).await;
| | --------
| | |
| | variable moved due to use in coroutine
| | move occurs because `props.id` has type `String`, which does not implement the `Copy` trait
24 | | });
| |_____^ `props.id` is moved here
|
help: clone the value before moving it into the closure
|
20 ~ use_future(move || {
21 + let value = props.id.clone();
22 ~ async move {
23 | let plot = Plot::new(Bar::new(props.x, props.y));
24 |
25 ~ new_plot(&value, &plot).await;
26 ~ }
27 ~ });
|
error[E0507]: cannot move out of `props.x`, a captured variable in an `FnMut` closure
--> src/lib.rs:20:24
|
19 | fn component(props: Props) {
| ----- captured outer variable
20 | use_future(move || async move {
| ________________-------_^
| | |
| | captured by this `FnMut` closure
21 | | let plot = Plot::new(Bar::new(props.x, props.y));
| | -------
| | |
| | variable moved due to use in coroutine
| | move occurs because `props.x` has type `Vec<i64>`, which does not implement the `Copy` trait
22 | |
23 | | new_plot(&props.id, &plot).await;
24 | | });
| |_____^ `props.x` is moved here
|
help: clone the value before moving it into the closure
|
20 ~ use_future(move || {
21 + let value = props.x.clone();
22 ~ async move {
23 ~ let plot = Plot::new(Bar::new(value, props.y));
24 |
25 | new_plot(&props.id, &plot).await;
26 ~ }
27 ~ });
|
error[E0507]: cannot move out of `props.y`, a captured variable in an `FnMut` closure
--> src/lib.rs:20:24
|
19 | fn component(props: Props) {
| ----- captured outer variable
20 | use_future(move || async move {
| ________________-------_^
| | |
| | captured by this `FnMut` closure
21 | | let plot = Plot::new(Bar::new(props.x, props.y));
| | -------
| | |
| | variable moved due to use in coroutine
| | move occurs because `props.y` has type `Vec<i64>`, which does not implement the `Copy` trait
22 | |
23 | | new_plot(&props.id, &plot).await;
24 | | });
| |_____^ `props.y` is moved here
|
help: clone the value before moving it into the closure
|
20 ~ use_future(move || {
21 + let value = props.y.clone();
22 ~ async move {
23 ~ let plot = Plot::new(Bar::new(props.x, value));
24 |
25 | new_plot(&props.id, &plot).await;
26 ~ }
27 ~ });
|
error[E0382]: borrow of partially moved value: `props`
--> src/lib.rs:27:13
|
20 | use_future(move || async move {
| ------- value partially moved into closure here
21 | let plot = Plot::new(Bar::new(props.x, props.y));
| ------- variable partially moved due to use in closure
...
27 | let _ = &props;
| ^^^^^^ value borrowed here after partial move
|
= note: partial move occurs because `props.y` has type `Vec<i64>`, which does not implement the `Copy` trait
My Workaround
To fix/workaround the error, I have to clone twice and I understand vaguely the reason for it.
- First cloning is to move them(
id1, x1, y1
) to the closure - Second cloning is to move (
id2, x2, y2
) to the async block
let id1 = props.id.clone();
let x1 = props.x.clone();
let y1 = props.y.clone();
use_future(move || {
let id2 = id1.clone();
let x2 = x.clone();
let y2 = y.clone();
async move {
let plot = Plot::new(Bar::new(x2, y2));
new_plot(&id2, &plot).await;
}
});