I've tried everything from Rc to Arc and Mutex async_std which wouldn't even compile despite it apparently including wasm support. I've been fighting with this error for a few days now and I can't fathom the problem when non-wasm seems to work fine and Promise no different. Tried it on not-self as well, using struct-less code, same problem.
use std::cell::RefCell;
use std::rc::Rc;
use wasm_bindgen_futures::spawn_local;
use wasm_bindgen::prelude::*;
pub struct MyClass {
value: u32,
}
impl MyClass {
pub fn new() -> Self {
return Self { value: 0 };
}
pub async fn boot_async(this: Rc<RefCell<&mut Self>>) {
this.borrow_mut().value += 1;
}
pub fn boot(&mut self) {
let this = Rc::new(RefCell::new(self));
let async_function = MyClass::boot_async(this.clone());
spawn_local(async_function);
}
}
#[wasm_bindgen(start)]
fn start() {
let mut test = MyClass::new();
test.boot();
}
And I get:
error[E0521]: borrowed data escapes outside of method
--> src/main.rs:29:30
|
27 | pub fn boot(&mut self) {
| ---------
| |
| `self` is a reference that is only valid in the method body
| let's call the lifetime of this reference `'1`
28 | let this = Rc::new(RefCell::new(self));
29 | let async_function = MyClass::boot_async(this.clone());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| `self` escapes the method body here
| argument requires that `'1` must outlive `'static`
|
= note: requirement occurs because of the type `RefCell<&mut MyClass>`, which makes the generic argument `&mut MyClass` invariant
= note: the struct `RefCell<T>` is invariant over the parameter `T`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
Your were close. The problem is that Rc
doesn't help since you still have a reference. You need to get rid of it:
impl MyClass {
pub fn new() -> Self {
return Self { value: 0 };
}
pub async fn boot_async(this: Rc<RefCell<Self>>) {
this.borrow_mut().value += 1;
}
pub fn boot(self) {
let this = Rc::new(RefCell::new(self));
let async_function = MyClass::boot_async(this.clone());
spawn_local(async_function);
}
}