Stream: git-wasmtime

Topic: wasmtime / issue #11700 How to deal with the `'static` in...


view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2025 at 08:00):

jdejaegh opened issue #11700:

Hello,

I recently updated the wasmtime dependency in one of my projects (from v32 to v36, to be on the LTS). I am mainly using the component model and resources. Since the update, I am having trouble understanding how to deal with the data in the Store.

Here is my use-case: I use components to update methods of structs at runtime. I wrote a procedural macro to generate the code needed to check if a component is available to update the method at runtime. If a component is available, I load it and call the corresponding function in the component. To have a meaningful example, I removed the procedural macro part and reduced the code to a minimum (non) working example.

In wasmtime v32, I could handle a call to a method as follows:

```rust
pub fn greet(&self) {
let plugin = get_wasm_component("person_plugin");
if let Ok((engine, component, mut linker)) = plugin {
let mut data = StatePerson::default();
let res_idx = 0_u32;
data.person_table.insert(res_idx, MaybePerson::NotMut(self));
let self_res = Resource::new_borrow(res_idx);

        let mut store = Store::new(&engine, data);
        person_bindings::example::plugin::imp::add_to_linker(&mut linker, |state| state).unwrap();
        person_bindings::example::plugin::printer::add_to_linker(&mut linker, |state| state).unwrap();

        let bindings = person_bindings::PersonPlugin::instantiate(&mut store, &component, &linker).unwrap();
        bindings.call_greet(&mut store, self_res).unwrap()
    } else { self.greet_internal() } 
}
Since I updated to wasmtime v36, I am unable to use this logic. The change was probably introduced in a version between 32 and 36 and is probably related to https://github.com/bytecodealliance/wasmtime/pull/10760.

I added the type annotations on `add_to_linker` as required, but the compiler complains about this:

```text

error[E0521]: borrowed data escapes outside of method
  --> src/main.rs:65:29
   |
57 |     pub fn greet(&self) {
   |                  -----
   |                  |
   |                  `self` is a reference that is only valid in the method body
   |                  let's call the lifetime of this reference `'1`
...
65 |             let mut store = Store::new(&engine, data);
   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^
   |                             |
   |                             `self` escapes the method body here
   |                             argument requires that `'1` must outlive `'static`

As I understand, the compiler wants me to have a 'static lifetime on self (which I don't really want to have). I tried to have the store destroyed at the end of the function by calling store.into_data() without success.

Is there a way to use wasmtime v36 in this setup?

Here is a minimum working example of my code: https://github.com/jdejaegh/wasmtime-32-to-36-bug

Thanks for the help :)

view this post on Zulip Wasmtime GitHub notifications bot (Sep 16 2025 at 13:23):

alexcrichton commented on issue #11700:

Thanks for the report, and this is indeed an intentional consequence of https://github.com/bytecodealliance/wasmtime/pull/10760. Unfortunately there's no simple trick to get previous code relying on non-'static values working like it was before. Various refactorings you could possibly apply are:

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2025 at 12:19):

jdejaegh closed issue #11700:

Hello,

I recently updated the wasmtime dependency in one of my projects (from v32 to v36, to be on the LTS). I am mainly using the component model and resources. Since the update, I am having trouble understanding how to deal with the data in the Store.

Here is my use-case: I use components to update methods of structs at runtime. I wrote a procedural macro to generate the code needed to check if a component is available to update the method at runtime. If a component is available, I load it and call the corresponding function in the component. To have a meaningful example, I removed the procedural macro part and reduced the code to a minimum (non) working example.

In wasmtime v32, I could handle a call to a method as follows:

```rust
pub fn greet(&self) {
let plugin = get_wasm_component("person_plugin");
if let Ok((engine, component, mut linker)) = plugin {
let mut data = StatePerson::default();
let res_idx = 0_u32;
data.person_table.insert(res_idx, MaybePerson::NotMut(self));
let self_res = Resource::new_borrow(res_idx);

        let mut store = Store::new(&engine, data);
        person_bindings::example::plugin::imp::add_to_linker(&mut linker, |state| state).unwrap();
        person_bindings::example::plugin::printer::add_to_linker(&mut linker, |state| state).unwrap();

        let bindings = person_bindings::PersonPlugin::instantiate(&mut store, &component, &linker).unwrap();
        bindings.call_greet(&mut store, self_res).unwrap()
    } else { self.greet_internal() } 
}
Since I updated to wasmtime v36, I am unable to use this logic. The change was probably introduced in a version between 32 and 36 and is probably related to https://github.com/bytecodealliance/wasmtime/pull/10760.

I added the type annotations on `add_to_linker` as required, but the compiler complains about this:

```text

error[E0521]: borrowed data escapes outside of method
  --> src/main.rs:65:29
   |
57 |     pub fn greet(&self) {
   |                  -----
   |                  |
   |                  `self` is a reference that is only valid in the method body
   |                  let's call the lifetime of this reference `'1`
...
65 |             let mut store = Store::new(&engine, data);
   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^
   |                             |
   |                             `self` escapes the method body here
   |                             argument requires that `'1` must outlive `'static`

As I understand, the compiler wants me to have a 'static lifetime on self (which I don't really want to have). I tried to have the store destroyed at the end of the function by calling store.into_data() without success.

Is there a way to use wasmtime v36 in this setup?

Here is a minimum working example of my code: https://github.com/jdejaegh/wasmtime-32-to-36-bug

Thanks for the help :)

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2025 at 12:19):

jdejaegh commented on issue #11700:

Thanks for the reply. Unfortunately, none of the options suggested worked with the example.

  1. Using a TLS requires that the data in there is 'static as well. This would include self which is not possible to have 'static here.
  2. The crate I want to produce should be "self-agnostic": what is in self should not prevent the call from working. The goal is to provide a macro to users so they can apply it on any struct and have some methods replaced by WebAssembly calls. I would like to avoid restricting what self can be.
  3. I did not investigate much in the last option.

I ended up using the unsafe std::mem::transmute similarly to what was done in wasmtime 32: convert the lifetime to 'static.

https://github.com/bytecodealliance/wasmtime/blob/v32.0.0/crates/wasmtime/src/runtime/store.rs#L609-L620

Here is how I applied it in my case:

     let mut data = StatePerson::default();
     let res_idx = 0_u32;
-    data.person_table.insert(res_idx, MaybePerson::NotMut(self));
+    data.person_table.insert(res_idx, MaybePerson::NotMut(unsafe {std::mem::transmute::<&'_ Person, &'static Person>(self)}));
     let self_res = Resource::new_borrow(res_idx);

     let mut store = Store::new(&engine, data);
 ```
~~~


Last updated: Dec 06 2025 at 06:05 UTC