Description
This issue is intended to be a tracking issue for behavior I'm about to commit to this repository, namely that when an async import's future in a Rust guest is dropped it will trap instead of cancel the future. Typically dropping a future means to cancel it in Rust but the component model does not yet at this time have a specification of how to cancel async tasks created through lowering imported functions. This means that there's no way that the import can actually be cancelled.
The reasons for this being a trap are:
- Current bindgen enables imported functions to use borrowed values on the stack. If the future were dropped then Rust thinks the values on the stack are no longer in use, but the component model would keep running the future, possibly leading to corruption. One possible fix to this, though, is to always generate bindings with "owned" arguments (e.g.
Vec<u8>
instead of&[u8]
) - If a
borrow<T>
is passed to an imported function then that's modeled in Rust as&ResourceT
. If the returned future is dropped then Rust thinks it's able to drop theResourceT
, but the component model doesn't allow that because the borrow is currently active from the perspective of the runtime (as the call hasn't actually been dropped).
In essence there's a mismatch in semantics for dropping/cancelling a future in Rust and the inability to do so in the component model at this time. While cancellation is planned for the component model it's not implemented/designed just yet. That all leads to the behavior that the Rust bindings generator emits today which is to abort-on-drop to guarantee that none of these footguns happen at runtime. It does unfortunately make another footgun of possibly leading to aborts in guests, but there's not many options to choose from alas at this time.