andrewweston opened issue #14218:
Summary
p3::Request::from_httpandp3::Response::from_httpreturn(Self, impl Future<Output = Result<(), Error>> + Send + 'static)Under the Rust 2024 edition capture rules, the opaque return type implicitly captures the elided lifetime of the
hooks: &mut dyn WasiHttpHooksparameter. The future's body never borrowshooks— it is only used synchronously (viaFieldMap::new_immutable) beforeSelf::newis called — but callers are constrained as if the borrow lived inside the future.Present in
wasmtime-wasi-http48.0.1 and onmain:
- https://github.com/bytecodealliance/wasmtime/blob/main/crates/wasi-http/src/p3/request.rs (
from_http)- https://github.com/bytecodealliance/wasmtime/blob/main/crates/wasi-http/src/p3/response.rs (
from_http)Why it matters
In the usual embedding, hooks live inside the store data behind
WasiHttpView::http(), so the natural call site is inside a short-lived store access (e.g.Accessor::withunderrun_concurrent). The returned future then cannot escape the closure:let (request, io) = store.with(|mut access| { let mut cx = access.as_context_mut(); Request::from_http(cx.data_mut().http().hooks, req) });error[E0515]: cannot return value referencing function parameter `access` note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules help: if you can modify this crate, add a precise capturing bound to avoid overcapturing: `+ use<T>`Suggested fix
Add precise-capture bounds so only the body type parameter is captured:
impl Future<Output = Result<(), Error>> + Send + 'static + use<T>on both
from_httpfunctions (Request::new/Response::neware unaffected — they have no borrowed inputs).Workaround
Decompose the request manually: build
FieldMap::new_immutable(hooks, headers)inside the store access, then assemble withRequest::newoutside it.
rvolosatovs closed issue #14218:
Summary
p3::Request::from_httpandp3::Response::from_httpreturn(Self, impl Future<Output = Result<(), Error>> + Send + 'static)Under the Rust 2024 edition capture rules, the opaque return type implicitly captures the elided lifetime of the
hooks: &mut dyn WasiHttpHooksparameter. The future's body never borrowshooks— it is only used synchronously (viaFieldMap::new_immutable) beforeSelf::newis called — but callers are constrained as if the borrow lived inside the future.Present in
wasmtime-wasi-http48.0.1 and onmain:
- https://github.com/bytecodealliance/wasmtime/blob/main/crates/wasi-http/src/p3/request.rs (
from_http)- https://github.com/bytecodealliance/wasmtime/blob/main/crates/wasi-http/src/p3/response.rs (
from_http)Why it matters
In the usual embedding, hooks live inside the store data behind
WasiHttpView::http(), so the natural call site is inside a short-lived store access (e.g.Accessor::withunderrun_concurrent). The returned future then cannot escape the closure:let (request, io) = store.with(|mut access| { let mut cx = access.as_context_mut(); Request::from_http(cx.data_mut().http().hooks, req) });error[E0515]: cannot return value referencing function parameter `access` note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules help: if you can modify this crate, add a precise capturing bound to avoid overcapturing: `+ use<T>`Suggested fix
Add precise-capture bounds so only the body type parameter is captured:
impl Future<Output = Result<(), Error>> + Send + 'static + use<T>on both
from_httpfunctions (Request::new/Response::neware unaffected — they have no borrowed inputs).Workaround
Decompose the request manually: build
FieldMap::new_immutable(hooks, headers)inside the store access, then assemble withRequest::newoutside it.
Last updated: Aug 30 2026 at 09:07 UTC