I have been wondering for a while why the bound on Store<T> is T: 'static. instead of having a Store<T, 'a> with the bound T: 'a instead. I don't understand why T has to outlive the Store that uses it. Is it because the store isn't capable to drop T when it is itself dropped ? Since T is taken by value at the store construction there isn't a way for that value to be used again once the store is dropped AFAIU...
Is the current because it was/is too complicated to propagate the lifetime constraints all over the machinery or is my understanding wrong ?
Propagating a lifetime everywhere would be pretty complicated yeah, but it also has to do with the component-model-async implementation where it, to us at least, unnecesarily requires that T: 'static when otherwise we shouldn't need it
Design rationale is here https://github.com/bytecodealliance/wasmtime/pull/10760
ah, you beat me to it
oh no that PR is better heh
I keep forgetting about that...
I still don't understand why it's needed in the first place. From that PR the only thing I got is that at some point (or maybe from the start of wasmtime) the compiler started asking for T: 'static bound and you tried to resist it by adding some transmuteto alleviate this but it ended up overwhelming so you decided instead to put T: 'static bounds everywhere (which is completely fair) but I don't understand the underlying reason that caused any T: 'static bound to show up in the first place
We added this constraint to Spin's embedding of Wasmtime long ago. One of the biggest problems for async is that futures need to be 'static in a lot of situations like for tokio::task::spawn.
The main cause of the compiler wanting this bound is that we store, for example, fn(T) in data structures where T is a generic parameter. That data structure isn't 'static unless T: 'static
(according to rustc, which we feel is a bug but can't do much about it)
Yeah, the rust-lang folks point to the well-formedness check on the type (any contained type must outlive the type) which makes sense when the value of that type is actually stored inside but a function arg is not that. I suppose the most one could push things if the restriction didn't exist is that a fn(T) of lifetime 'static could live beyond when any valid T exists that would fit, which is odd (uninhabitable callsite param) but not unsound. shrug
(of course I could be missing something subtle here but my point is that at least it doesn't seem like an obvious "type system insists, sorry end of story")
Last updated: Dec 06 2025 at 06:05 UTC