I'm trying to borrow (not mutably) a variable in an FnMut closure. As soon as I have an await
in there, the compiler complains, even though I do everything I can to avoid having the reference
in scope accross the await point. Even adding an extra scope or cloning an Rc won't do...
I would like to avoid calling get_element_by_id
in the loop. handle_send
is a task that will be spawned.
error: captured variable cannot escape `FnMut` closure body
--> src/entrypoint.rs:95:23
|
95 | stream.for_each( |_| async
| ________________________-_^
| | |
| | inferred to be a `FnMut` closure
96 | | {
97 | | let text;
98 | |
... |
108 | |
109 | | }).await;
| |______^ returns a reference to a captured variable which escapes the closure body
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
error: aborting due to previous error
This code runs in wasm. Ideally I wouldn't use the Rc
. Note that nothing requires mutable access to textarea
async fn handle_send( on_clicks: impl Stream<Item=()>, mut out: impl Sink<String> + Unpin )
{
let window = web_sys::window ().expect_throw( "no global `window` exists" );
let document = window .document().expect_throw( "should have a document on window" );
let textarea = document.get_element_by_id( "chat_input" ).expect_throw( "find chat_input" );
let ta = Rc::new( textarea );
on_clicks.for_each( |_| async
{
let text;
{
let ta = ta.clone();
// same error when just using textarea here.
//
let text = ta.text_content();
ta.set_text_content( None );
}
if let Some( t ) = text
{
// This line causes the error
//
out.send( t ).await;
}
}).await;
}