diff --git a/crates/component-macro/src/bindgen.rs b/crates/component-macro/src/bindgen.rs index 4b55c924a58..e35b20af65b 100644 --- a/crates/component-macro/src/bindgen.rs +++ b/crates/component-macro/src/bindgen.rs @@ -149,6 +149,7 @@ impl Parse for Config { .collect() } Opt::Stringify(val) => opts.stringify = val, + Opt::SkipMutForwardingImpls(val) => opts.skip_mut_forwarding_impls = val, } } } else { @@ -219,6 +220,7 @@ mod kw { syn::custom_keyword!(trappable_imports); syn::custom_keyword!(additional_derives); syn::custom_keyword!(stringify); + syn::custom_keyword!(skip_mut_forwarding_impls); } enum Opt { @@ -234,6 +236,7 @@ enum Opt { TrappableImports(TrappableImports), AdditionalDerives(Vec), Stringify(bool), + SkipMutForwardingImpls(bool), } impl Parse for Opt { @@ -378,6 +381,12 @@ impl Parse for Opt { input.parse::()?; input.parse::()?; Ok(Opt::Stringify(input.parse::()?.value)) + } else if l.peek(kw::skip_mut_forwarding_impls) { + input.parse::()?; + input.parse::()?; + Ok(Opt::SkipMutForwardingImpls( + input.parse::()?.value, + )) } else { Err(l.error()) } diff --git a/crates/component-macro/tests/expanded/char.rs b/crates/component-macro/tests/expanded/char.rs index 4aece793b1c..a9115c2ad89 100644 --- a/crates/component-macro/tests/expanded/char.rs +++ b/crates/component-macro/tests/expanded/char.rs @@ -77,13 +77,22 @@ pub mod foo { /// A function that returns a character fn return_char(&mut self) -> char; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/chars")?; inst.func_wrap( "take-char", @@ -91,7 +100,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (char,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::take_char(host, arg0); Ok(r) }, @@ -99,13 +108,32 @@ pub mod foo { inst.func_wrap( "return-char", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_char(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + /// A function that accepts a character + fn take_char(&mut self, x: char) -> () { + Host::take_char(*self, x) + } + /// A function that returns a character + fn return_char(&mut self) -> char { + Host::return_char(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/char_async.rs b/crates/component-macro/tests/expanded/char_async.rs index e3971a68d08..2b79271240a 100644 --- a/crates/component-macro/tests/expanded/char_async.rs +++ b/crates/component-macro/tests/expanded/char_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::chars::Host + Send, T: Send, + U: foo::foo::chars::Host + Send, { foo::foo::chars::add_to_linker(linker, get)?; Ok(()) @@ -73,19 +73,30 @@ pub mod foo { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { /// A function that accepts a character async fn take_char(&mut self, x: char) -> (); /// A function that returns a character async fn return_char(&mut self) -> char; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/chars")?; inst.func_wrap_async( @@ -94,7 +105,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (char,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::take_char(host, arg0).await; Ok(r) }), @@ -102,13 +113,34 @@ pub mod foo { inst.func_wrap_async( "return-char", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_char(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + /// A function that accepts a character + async fn take_char(&mut self, x: char) -> () { + Host::take_char(*self, x).await + } + /// A function that returns a character + async fn return_char(&mut self) -> char { + Host::return_char(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/conventions.rs b/crates/component-macro/tests/expanded/conventions.rs index 56fd70e2f3f..cb9290805c4 100644 --- a/crates/component-macro/tests/expanded/conventions.rs +++ b/crates/component-macro/tests/expanded/conventions.rs @@ -125,18 +125,27 @@ pub mod foo { /// Identifiers with the same name as keywords are quoted. fn bool(&mut self) -> (); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/conventions")?; inst.func_wrap( "kebab-case", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::kebab_case(host); Ok(r) }, @@ -147,7 +156,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (LudicrousSpeed,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::foo(host, arg0); Ok(r) }, @@ -155,7 +164,7 @@ pub mod foo { inst.func_wrap( "function-with-dashes", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::function_with_dashes(host); Ok(r) }, @@ -163,7 +172,7 @@ pub mod foo { inst.func_wrap( "function-with-no-weird-characters", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::function_with_no_weird_characters(host); Ok(r) }, @@ -171,7 +180,7 @@ pub mod foo { inst.func_wrap( "apple", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::apple(host); Ok(r) }, @@ -179,7 +188,7 @@ pub mod foo { inst.func_wrap( "apple-pear", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::apple_pear(host); Ok(r) }, @@ -187,7 +196,7 @@ pub mod foo { inst.func_wrap( "apple-pear-grape", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::apple_pear_grape(host); Ok(r) }, @@ -195,7 +204,7 @@ pub mod foo { inst.func_wrap( "a0", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a0(host); Ok(r) }, @@ -203,7 +212,7 @@ pub mod foo { inst.func_wrap( "is-XML", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::is_xml(host); Ok(r) }, @@ -211,7 +220,7 @@ pub mod foo { inst.func_wrap( "explicit", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::explicit(host); Ok(r) }, @@ -219,7 +228,7 @@ pub mod foo { inst.func_wrap( "explicit-kebab", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::explicit_kebab(host); Ok(r) }, @@ -227,13 +236,66 @@ pub mod foo { inst.func_wrap( "bool", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bool(host); Ok(r) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn kebab_case(&mut self) -> () { + Host::kebab_case(*self) + } + fn foo(&mut self, x: LudicrousSpeed) -> () { + Host::foo(*self, x) + } + fn function_with_dashes(&mut self) -> () { + Host::function_with_dashes(*self) + } + fn function_with_no_weird_characters(&mut self) -> () { + Host::function_with_no_weird_characters(*self) + } + fn apple(&mut self) -> () { + Host::apple(*self) + } + fn apple_pear(&mut self) -> () { + Host::apple_pear(*self) + } + fn apple_pear_grape(&mut self) -> () { + Host::apple_pear_grape(*self) + } + fn a0(&mut self) -> () { + Host::a0(*self) + } + /// Comment out identifiers that collide when mapped to snake_case, for now; see + /// https://github.com/WebAssembly/component-model/issues/118 + /// APPLE: func() + /// APPLE-pear-GRAPE: func() + /// apple-PEAR-grape: func() + fn is_xml(&mut self) -> () { + Host::is_xml(*self) + } + fn explicit(&mut self) -> () { + Host::explicit(*self) + } + fn explicit_kebab(&mut self) -> () { + Host::explicit_kebab(*self) + } + /// Identifiers with the same name as keywords are quoted. + fn bool(&mut self) -> () { + Host::bool(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/conventions_async.rs b/crates/component-macro/tests/expanded/conventions_async.rs index afbf0f1bed3..ebb02fb0653 100644 --- a/crates/component-macro/tests/expanded/conventions_async.rs +++ b/crates/component-macro/tests/expanded/conventions_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::conventions::Host + Send, T: Send, + U: foo::foo::conventions::Host + Send, { foo::foo::conventions::add_to_linker(linker, get)?; Ok(()) @@ -107,7 +107,7 @@ pub mod foo { ); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn kebab_case(&mut self) -> (); async fn foo(&mut self, x: LudicrousSpeed) -> (); async fn function_with_dashes(&mut self) -> (); @@ -127,19 +127,30 @@ pub mod foo { /// Identifiers with the same name as keywords are quoted. async fn bool(&mut self) -> (); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/conventions")?; inst.func_wrap_async( "kebab-case", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::kebab_case(host).await; Ok(r) }), @@ -150,7 +161,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (LudicrousSpeed,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::foo(host, arg0).await; Ok(r) }), @@ -158,7 +169,7 @@ pub mod foo { inst.func_wrap_async( "function-with-dashes", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::function_with_dashes(host).await; Ok(r) }), @@ -166,7 +177,7 @@ pub mod foo { inst.func_wrap_async( "function-with-no-weird-characters", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::function_with_no_weird_characters(host).await; Ok(r) }), @@ -174,7 +185,7 @@ pub mod foo { inst.func_wrap_async( "apple", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::apple(host).await; Ok(r) }), @@ -182,7 +193,7 @@ pub mod foo { inst.func_wrap_async( "apple-pear", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::apple_pear(host).await; Ok(r) }), @@ -190,7 +201,7 @@ pub mod foo { inst.func_wrap_async( "apple-pear-grape", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::apple_pear_grape(host).await; Ok(r) }), @@ -198,7 +209,7 @@ pub mod foo { inst.func_wrap_async( "a0", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a0(host).await; Ok(r) }), @@ -206,7 +217,7 @@ pub mod foo { inst.func_wrap_async( "is-XML", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::is_xml(host).await; Ok(r) }), @@ -214,7 +225,7 @@ pub mod foo { inst.func_wrap_async( "explicit", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::explicit(host).await; Ok(r) }), @@ -222,7 +233,7 @@ pub mod foo { inst.func_wrap_async( "explicit-kebab", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::explicit_kebab(host).await; Ok(r) }), @@ -230,13 +241,68 @@ pub mod foo { inst.func_wrap_async( "bool", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bool(host).await; Ok(r) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn kebab_case(&mut self) -> () { + Host::kebab_case(*self).await + } + async fn foo(&mut self, x: LudicrousSpeed) -> () { + Host::foo(*self, x).await + } + async fn function_with_dashes(&mut self) -> () { + Host::function_with_dashes(*self).await + } + async fn function_with_no_weird_characters(&mut self) -> () { + Host::function_with_no_weird_characters(*self).await + } + async fn apple(&mut self) -> () { + Host::apple(*self).await + } + async fn apple_pear(&mut self) -> () { + Host::apple_pear(*self).await + } + async fn apple_pear_grape(&mut self) -> () { + Host::apple_pear_grape(*self).await + } + async fn a0(&mut self) -> () { + Host::a0(*self).await + } + /// Comment out identifiers that collide when mapped to snake_case, for now; see + /// https://github.com/WebAssembly/component-model/issues/118 + /// APPLE: func() + /// APPLE-pear-GRAPE: func() + /// apple-PEAR-grape: func() + async fn is_xml(&mut self) -> () { + Host::is_xml(*self).await + } + async fn explicit(&mut self) -> () { + Host::explicit(*self).await + } + async fn explicit_kebab(&mut self) -> () { + Host::explicit_kebab(*self).await + } + /// Identifiers with the same name as keywords are quoted. + async fn bool(&mut self) -> () { + Host::bool(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/dead-code.rs b/crates/component-macro/tests/expanded/dead-code.rs index 600f5f49fa9..6734e3206ec 100644 --- a/crates/component-macro/tests/expanded/dead-code.rs +++ b/crates/component-macro/tests/expanded/dead-code.rs @@ -84,30 +84,72 @@ pub mod a { pub trait Host { fn f(&mut self) -> LiveType; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("a:b/interface-with-live-type")?; inst.func_wrap( "f", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn f(&mut self) -> LiveType { + Host::f(*self) + } + } } #[allow(clippy::all)] pub mod interface_with_dead_type { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; pub trait Host {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { + let mut inst = linker.instance("a:b/interface-with-dead-type")?; + Ok(()) + } pub fn add_to_linker( linker: &mut wasmtime::component::Linker, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, @@ -115,9 +157,9 @@ pub mod a { where U: Host, { - let mut inst = linker.instance("a:b/interface-with-dead-type")?; - Ok(()) + add_to_linker_get_host(linker, get) } + impl<_T: Host + ?Sized> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/dead-code_async.rs b/crates/component-macro/tests/expanded/dead-code_async.rs index d2ef5c89377..ed7d7e401b9 100644 --- a/crates/component-macro/tests/expanded/dead-code_async.rs +++ b/crates/component-macro/tests/expanded/dead-code_async.rs @@ -8,9 +8,9 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where + T: Send, U: a::b::interface_with_live_type::Host + a::b::interface_with_dead_type::Host + Send, - T: Send, { a::b::interface_with_live_type::add_to_linker(linker, get)?; a::b::interface_with_dead_type::add_to_linker(linker, get)?; @@ -83,46 +83,96 @@ pub mod a { ); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn f(&mut self) -> LiveType; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("a:b/interface-with-live-type")?; inst.func_wrap_async( "f", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn f(&mut self) -> LiveType { + Host::f(*self).await + } + } } #[allow(clippy::all)] pub mod interface_with_dead_type { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host {} - pub fn add_to_linker( + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("a:b/interface-with-dead-type")?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/direct-import.rs b/crates/component-macro/tests/expanded/direct-import.rs index abef9fe2088..fe627871f83 100644 --- a/crates/component-macro/tests/expanded/direct-import.rs +++ b/crates/component-macro/tests/expanded/direct-import.rs @@ -2,39 +2,53 @@ pub struct Foo {} pub trait FooImports { fn foo(&mut self) -> (); } +pub trait FooImportsGetHost< + T, +>: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: FooImports; +} +impl FooImportsGetHost for F +where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: FooImports, +{ + type Host = O; +} +impl<_T: FooImports + ?Sized> FooImports for &mut _T { + fn foo(&mut self) -> () { + FooImports::foo(*self) + } +} const _: () = { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; impl Foo { - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> - where - U: FooImports, - { - Self::add_root_to_linker(linker, get)?; - Ok(()) - } - pub fn add_root_to_linker( + pub fn add_to_linker_imports_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> - where - U: FooImports, - { + host_getter: impl for<'a> FooImportsGetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut linker = linker.root(); linker .func_wrap( "foo", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = FooImports::foo(host); Ok(r) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: FooImports, + { + Self::add_to_linker_imports_get_host(linker, get)?; + Ok(()) + } /// Instantiates the provided `module` using the specified /// parameters, wrapping up the result in a structure that /// translates between wasm and the host. diff --git a/crates/component-macro/tests/expanded/direct-import_async.rs b/crates/component-macro/tests/expanded/direct-import_async.rs index 1f6c9a6282f..de7b0490066 100644 --- a/crates/component-macro/tests/expanded/direct-import_async.rs +++ b/crates/component-macro/tests/expanded/direct-import_async.rs @@ -1,29 +1,35 @@ pub struct Foo {} #[wasmtime::component::__internal::async_trait] -pub trait FooImports { +pub trait FooImports: Send { async fn foo(&mut self) -> (); } +pub trait FooImportsGetHost< + T, +>: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: FooImports; +} +impl FooImportsGetHost for F +where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: FooImports, +{ + type Host = O; +} +#[wasmtime::component::__internal::async_trait] +impl<_T: FooImports + ?Sized + Send> FooImports for &mut _T { + async fn foo(&mut self) -> () { + FooImports::foo(*self).await + } +} const _: () = { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; impl Foo { - pub fn add_to_linker( + pub fn add_to_linker_imports_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> FooImportsGetHost<&'a mut T>, ) -> wasmtime::Result<()> where - U: FooImports + Send, - T: Send, - { - Self::add_root_to_linker(linker, get)?; - Ok(()) - } - pub fn add_root_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> - where - U: FooImports + Send, T: Send, { let mut linker = linker.root(); @@ -31,13 +37,24 @@ const _: () = { .func_wrap_async( "foo", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = FooImports::foo(host).await; Ok(r) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: FooImports + Send, + { + Self::add_to_linker_imports_get_host(linker, get)?; + Ok(()) + } /// Instantiates the provided `module` using the specified /// parameters, wrapping up the result in a structure that /// translates between wasm and the host. diff --git a/crates/component-macro/tests/expanded/flags.rs b/crates/component-macro/tests/expanded/flags.rs index 48b4929acce..d718d765056 100644 --- a/crates/component-macro/tests/expanded/flags.rs +++ b/crates/component-macro/tests/expanded/flags.rs @@ -194,13 +194,22 @@ pub mod foo { fn roundtrip_flag32(&mut self, x: Flag32) -> Flag32; fn roundtrip_flag64(&mut self, x: Flag64) -> Flag64; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/flegs")?; inst.func_wrap( "roundtrip-flag1", @@ -208,7 +217,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag1,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag1(host, arg0); Ok((r,)) }, @@ -219,7 +228,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag2,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag2(host, arg0); Ok((r,)) }, @@ -230,7 +239,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag4,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag4(host, arg0); Ok((r,)) }, @@ -241,7 +250,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag8,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag8(host, arg0); Ok((r,)) }, @@ -252,7 +261,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag16,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag16(host, arg0); Ok((r,)) }, @@ -263,7 +272,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag32,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag32(host, arg0); Ok((r,)) }, @@ -274,13 +283,45 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag64,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag64(host, arg0); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn roundtrip_flag1(&mut self, x: Flag1) -> Flag1 { + Host::roundtrip_flag1(*self, x) + } + fn roundtrip_flag2(&mut self, x: Flag2) -> Flag2 { + Host::roundtrip_flag2(*self, x) + } + fn roundtrip_flag4(&mut self, x: Flag4) -> Flag4 { + Host::roundtrip_flag4(*self, x) + } + fn roundtrip_flag8(&mut self, x: Flag8) -> Flag8 { + Host::roundtrip_flag8(*self, x) + } + fn roundtrip_flag16(&mut self, x: Flag16) -> Flag16 { + Host::roundtrip_flag16(*self, x) + } + fn roundtrip_flag32(&mut self, x: Flag32) -> Flag32 { + Host::roundtrip_flag32(*self, x) + } + fn roundtrip_flag64(&mut self, x: Flag64) -> Flag64 { + Host::roundtrip_flag64(*self, x) + } + } } } } diff --git a/crates/component-macro/tests/expanded/flags_async.rs b/crates/component-macro/tests/expanded/flags_async.rs index 40e90b2121c..34b93a1c2cc 100644 --- a/crates/component-macro/tests/expanded/flags_async.rs +++ b/crates/component-macro/tests/expanded/flags_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::flegs::Host + Send, T: Send, + U: foo::foo::flegs::Host + Send, { foo::foo::flegs::add_to_linker(linker, get)?; Ok(()) @@ -187,7 +187,7 @@ pub mod foo { assert!(4 == < Flag64 as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn roundtrip_flag1(&mut self, x: Flag1) -> Flag1; async fn roundtrip_flag2(&mut self, x: Flag2) -> Flag2; async fn roundtrip_flag4(&mut self, x: Flag4) -> Flag4; @@ -196,13 +196,24 @@ pub mod foo { async fn roundtrip_flag32(&mut self, x: Flag32) -> Flag32; async fn roundtrip_flag64(&mut self, x: Flag64) -> Flag64; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/flegs")?; inst.func_wrap_async( @@ -211,7 +222,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag1,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag1(host, arg0).await; Ok((r,)) }), @@ -222,7 +233,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag2,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag2(host, arg0).await; Ok((r,)) }), @@ -233,7 +244,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag4,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag4(host, arg0).await; Ok((r,)) }), @@ -244,7 +255,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag8,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag8(host, arg0).await; Ok((r,)) }), @@ -255,7 +266,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag16,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag16(host, arg0).await; Ok((r,)) }), @@ -266,7 +277,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag32,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag32(host, arg0).await; Ok((r,)) }), @@ -277,13 +288,47 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Flag64,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::roundtrip_flag64(host, arg0).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn roundtrip_flag1(&mut self, x: Flag1) -> Flag1 { + Host::roundtrip_flag1(*self, x).await + } + async fn roundtrip_flag2(&mut self, x: Flag2) -> Flag2 { + Host::roundtrip_flag2(*self, x).await + } + async fn roundtrip_flag4(&mut self, x: Flag4) -> Flag4 { + Host::roundtrip_flag4(*self, x).await + } + async fn roundtrip_flag8(&mut self, x: Flag8) -> Flag8 { + Host::roundtrip_flag8(*self, x).await + } + async fn roundtrip_flag16(&mut self, x: Flag16) -> Flag16 { + Host::roundtrip_flag16(*self, x).await + } + async fn roundtrip_flag32(&mut self, x: Flag32) -> Flag32 { + Host::roundtrip_flag32(*self, x).await + } + async fn roundtrip_flag64(&mut self, x: Flag64) -> Flag64 { + Host::roundtrip_flag64(*self, x).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/floats.rs b/crates/component-macro/tests/expanded/floats.rs index 7c7f2d02ce5..eacca26c064 100644 --- a/crates/component-macro/tests/expanded/floats.rs +++ b/crates/component-macro/tests/expanded/floats.rs @@ -77,18 +77,27 @@ pub mod foo { fn float32_result(&mut self) -> f32; fn float64_result(&mut self) -> f64; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/floats")?; inst.func_wrap( "float32-param", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (f32,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::float32_param(host, arg0); Ok(r) }, @@ -96,7 +105,7 @@ pub mod foo { inst.func_wrap( "float64-param", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (f64,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::float64_param(host, arg0); Ok(r) }, @@ -104,7 +113,7 @@ pub mod foo { inst.func_wrap( "float32-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::float32_result(host); Ok((r,)) }, @@ -112,13 +121,36 @@ pub mod foo { inst.func_wrap( "float64-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::float64_result(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn float32_param(&mut self, x: f32) -> () { + Host::float32_param(*self, x) + } + fn float64_param(&mut self, x: f64) -> () { + Host::float64_param(*self, x) + } + fn float32_result(&mut self) -> f32 { + Host::float32_result(*self) + } + fn float64_result(&mut self) -> f64 { + Host::float64_result(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/floats_async.rs b/crates/component-macro/tests/expanded/floats_async.rs index 3dd8afe7f2c..bddb518bb3e 100644 --- a/crates/component-macro/tests/expanded/floats_async.rs +++ b/crates/component-macro/tests/expanded/floats_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::floats::Host + Send, T: Send, + U: foo::foo::floats::Host + Send, { foo::foo::floats::add_to_linker(linker, get)?; Ok(()) @@ -73,25 +73,36 @@ pub mod foo { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn float32_param(&mut self, x: f32) -> (); async fn float64_param(&mut self, x: f64) -> (); async fn float32_result(&mut self) -> f32; async fn float64_result(&mut self) -> f64; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/floats")?; inst.func_wrap_async( "float32-param", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (f32,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::float32_param(host, arg0).await; Ok(r) }), @@ -99,7 +110,7 @@ pub mod foo { inst.func_wrap_async( "float64-param", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (f64,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::float64_param(host, arg0).await; Ok(r) }), @@ -107,7 +118,7 @@ pub mod foo { inst.func_wrap_async( "float32-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::float32_result(host).await; Ok((r,)) }), @@ -115,13 +126,38 @@ pub mod foo { inst.func_wrap_async( "float64-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::float64_result(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn float32_param(&mut self, x: f32) -> () { + Host::float32_param(*self, x).await + } + async fn float64_param(&mut self, x: f64) -> () { + Host::float64_param(*self, x).await + } + async fn float32_result(&mut self) -> f32 { + Host::float32_result(*self).await + } + async fn float64_result(&mut self) -> f64 { + Host::float64_result(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/integers.rs b/crates/component-macro/tests/expanded/integers.rs index 8ae8fae0781..1d36e4cdcfa 100644 --- a/crates/component-macro/tests/expanded/integers.rs +++ b/crates/component-macro/tests/expanded/integers.rs @@ -103,18 +103,27 @@ pub mod foo { fn r8(&mut self) -> i64; fn pair_ret(&mut self) -> (i64, u8); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/integers")?; inst.func_wrap( "a1", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u8,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a1(host, arg0); Ok(r) }, @@ -122,7 +131,7 @@ pub mod foo { inst.func_wrap( "a2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i8,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a2(host, arg0); Ok(r) }, @@ -130,7 +139,7 @@ pub mod foo { inst.func_wrap( "a3", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u16,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a3(host, arg0); Ok(r) }, @@ -138,7 +147,7 @@ pub mod foo { inst.func_wrap( "a4", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i16,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a4(host, arg0); Ok(r) }, @@ -146,7 +155,7 @@ pub mod foo { inst.func_wrap( "a5", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u32,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a5(host, arg0); Ok(r) }, @@ -154,7 +163,7 @@ pub mod foo { inst.func_wrap( "a6", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i32,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a6(host, arg0); Ok(r) }, @@ -162,7 +171,7 @@ pub mod foo { inst.func_wrap( "a7", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u64,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a7(host, arg0); Ok(r) }, @@ -170,7 +179,7 @@ pub mod foo { inst.func_wrap( "a8", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i64,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a8(host, arg0); Ok(r) }, @@ -190,7 +199,7 @@ pub mod foo { arg7, ): (u8, i8, u16, i16, u32, i32, u64, i64)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a9( host, arg0, @@ -208,7 +217,7 @@ pub mod foo { inst.func_wrap( "r1", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r1(host); Ok((r,)) }, @@ -216,7 +225,7 @@ pub mod foo { inst.func_wrap( "r2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r2(host); Ok((r,)) }, @@ -224,7 +233,7 @@ pub mod foo { inst.func_wrap( "r3", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r3(host); Ok((r,)) }, @@ -232,7 +241,7 @@ pub mod foo { inst.func_wrap( "r4", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r4(host); Ok((r,)) }, @@ -240,7 +249,7 @@ pub mod foo { inst.func_wrap( "r5", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r5(host); Ok((r,)) }, @@ -248,7 +257,7 @@ pub mod foo { inst.func_wrap( "r6", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r6(host); Ok((r,)) }, @@ -256,7 +265,7 @@ pub mod foo { inst.func_wrap( "r7", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r7(host); Ok((r,)) }, @@ -264,7 +273,7 @@ pub mod foo { inst.func_wrap( "r8", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r8(host); Ok((r,)) }, @@ -272,13 +281,88 @@ pub mod foo { inst.func_wrap( "pair-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::pair_ret(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn a1(&mut self, x: u8) -> () { + Host::a1(*self, x) + } + fn a2(&mut self, x: i8) -> () { + Host::a2(*self, x) + } + fn a3(&mut self, x: u16) -> () { + Host::a3(*self, x) + } + fn a4(&mut self, x: i16) -> () { + Host::a4(*self, x) + } + fn a5(&mut self, x: u32) -> () { + Host::a5(*self, x) + } + fn a6(&mut self, x: i32) -> () { + Host::a6(*self, x) + } + fn a7(&mut self, x: u64) -> () { + Host::a7(*self, x) + } + fn a8(&mut self, x: i64) -> () { + Host::a8(*self, x) + } + fn a9( + &mut self, + p1: u8, + p2: i8, + p3: u16, + p4: i16, + p5: u32, + p6: i32, + p7: u64, + p8: i64, + ) -> () { + Host::a9(*self, p1, p2, p3, p4, p5, p6, p7, p8) + } + fn r1(&mut self) -> u8 { + Host::r1(*self) + } + fn r2(&mut self) -> i8 { + Host::r2(*self) + } + fn r3(&mut self) -> u16 { + Host::r3(*self) + } + fn r4(&mut self) -> i16 { + Host::r4(*self) + } + fn r5(&mut self) -> u32 { + Host::r5(*self) + } + fn r6(&mut self) -> i32 { + Host::r6(*self) + } + fn r7(&mut self) -> u64 { + Host::r7(*self) + } + fn r8(&mut self) -> i64 { + Host::r8(*self) + } + fn pair_ret(&mut self) -> (i64, u8) { + Host::pair_ret(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/integers_async.rs b/crates/component-macro/tests/expanded/integers_async.rs index ab9890524ce..9bec30c59c4 100644 --- a/crates/component-macro/tests/expanded/integers_async.rs +++ b/crates/component-macro/tests/expanded/integers_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::integers::Host + Send, T: Send, + U: foo::foo::integers::Host + Send, { foo::foo::integers::add_to_linker(linker, get)?; Ok(()) @@ -75,7 +75,7 @@ pub mod foo { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn a1(&mut self, x: u8) -> (); async fn a2(&mut self, x: i8) -> (); async fn a3(&mut self, x: u16) -> (); @@ -105,19 +105,30 @@ pub mod foo { async fn r8(&mut self) -> i64; async fn pair_ret(&mut self) -> (i64, u8); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/integers")?; inst.func_wrap_async( "a1", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u8,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a1(host, arg0).await; Ok(r) }), @@ -125,7 +136,7 @@ pub mod foo { inst.func_wrap_async( "a2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i8,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a2(host, arg0).await; Ok(r) }), @@ -133,7 +144,7 @@ pub mod foo { inst.func_wrap_async( "a3", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u16,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a3(host, arg0).await; Ok(r) }), @@ -141,7 +152,7 @@ pub mod foo { inst.func_wrap_async( "a4", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i16,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a4(host, arg0).await; Ok(r) }), @@ -149,7 +160,7 @@ pub mod foo { inst.func_wrap_async( "a5", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u32,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a5(host, arg0).await; Ok(r) }), @@ -157,7 +168,7 @@ pub mod foo { inst.func_wrap_async( "a6", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i32,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a6(host, arg0).await; Ok(r) }), @@ -165,7 +176,7 @@ pub mod foo { inst.func_wrap_async( "a7", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u64,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a7(host, arg0).await; Ok(r) }), @@ -173,7 +184,7 @@ pub mod foo { inst.func_wrap_async( "a8", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (i64,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a8(host, arg0).await; Ok(r) }), @@ -193,7 +204,7 @@ pub mod foo { arg7, ): (u8, i8, u16, i16, u32, i32, u64, i64)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a9( host, arg0, @@ -212,7 +223,7 @@ pub mod foo { inst.func_wrap_async( "r1", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r1(host).await; Ok((r,)) }), @@ -220,7 +231,7 @@ pub mod foo { inst.func_wrap_async( "r2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r2(host).await; Ok((r,)) }), @@ -228,7 +239,7 @@ pub mod foo { inst.func_wrap_async( "r3", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r3(host).await; Ok((r,)) }), @@ -236,7 +247,7 @@ pub mod foo { inst.func_wrap_async( "r4", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r4(host).await; Ok((r,)) }), @@ -244,7 +255,7 @@ pub mod foo { inst.func_wrap_async( "r5", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r5(host).await; Ok((r,)) }), @@ -252,7 +263,7 @@ pub mod foo { inst.func_wrap_async( "r6", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r6(host).await; Ok((r,)) }), @@ -260,7 +271,7 @@ pub mod foo { inst.func_wrap_async( "r7", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r7(host).await; Ok((r,)) }), @@ -268,7 +279,7 @@ pub mod foo { inst.func_wrap_async( "r8", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::r8(host).await; Ok((r,)) }), @@ -276,13 +287,90 @@ pub mod foo { inst.func_wrap_async( "pair-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::pair_ret(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a1(&mut self, x: u8) -> () { + Host::a1(*self, x).await + } + async fn a2(&mut self, x: i8) -> () { + Host::a2(*self, x).await + } + async fn a3(&mut self, x: u16) -> () { + Host::a3(*self, x).await + } + async fn a4(&mut self, x: i16) -> () { + Host::a4(*self, x).await + } + async fn a5(&mut self, x: u32) -> () { + Host::a5(*self, x).await + } + async fn a6(&mut self, x: i32) -> () { + Host::a6(*self, x).await + } + async fn a7(&mut self, x: u64) -> () { + Host::a7(*self, x).await + } + async fn a8(&mut self, x: i64) -> () { + Host::a8(*self, x).await + } + async fn a9( + &mut self, + p1: u8, + p2: i8, + p3: u16, + p4: i16, + p5: u32, + p6: i32, + p7: u64, + p8: i64, + ) -> () { + Host::a9(*self, p1, p2, p3, p4, p5, p6, p7, p8).await + } + async fn r1(&mut self) -> u8 { + Host::r1(*self).await + } + async fn r2(&mut self) -> i8 { + Host::r2(*self).await + } + async fn r3(&mut self) -> u16 { + Host::r3(*self).await + } + async fn r4(&mut self) -> i16 { + Host::r4(*self).await + } + async fn r5(&mut self) -> u32 { + Host::r5(*self).await + } + async fn r6(&mut self) -> i32 { + Host::r6(*self).await + } + async fn r7(&mut self) -> u64 { + Host::r7(*self).await + } + async fn r8(&mut self) -> i64 { + Host::r8(*self).await + } + async fn pair_ret(&mut self) -> (i64, u8) { + Host::pair_ret(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/lists.rs b/crates/component-macro/tests/expanded/lists.rs index 0160d6deb95..e404f16c9a1 100644 --- a/crates/component-macro/tests/expanded/lists.rs +++ b/crates/component-macro/tests/expanded/lists.rs @@ -354,13 +354,22 @@ pub mod foo { a: LoadStoreAllSizes, ) -> LoadStoreAllSizes; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/lists")?; inst.func_wrap( "list-u8-param", @@ -368,7 +377,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u8_param(host, arg0); Ok(r) }, @@ -379,7 +388,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u16_param(host, arg0); Ok(r) }, @@ -390,7 +399,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u32_param(host, arg0); Ok(r) }, @@ -401,7 +410,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u64_param(host, arg0); Ok(r) }, @@ -412,7 +421,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s8_param(host, arg0); Ok(r) }, @@ -423,7 +432,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s16_param(host, arg0); Ok(r) }, @@ -434,7 +443,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s32_param(host, arg0); Ok(r) }, @@ -445,7 +454,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s64_param(host, arg0); Ok(r) }, @@ -456,7 +465,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_float32_param(host, arg0); Ok(r) }, @@ -467,7 +476,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_float64_param(host, arg0); Ok(r) }, @@ -475,7 +484,7 @@ pub mod foo { inst.func_wrap( "list-u8-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u8_ret(host); Ok((r,)) }, @@ -483,7 +492,7 @@ pub mod foo { inst.func_wrap( "list-u16-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u16_ret(host); Ok((r,)) }, @@ -491,7 +500,7 @@ pub mod foo { inst.func_wrap( "list-u32-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u32_ret(host); Ok((r,)) }, @@ -499,7 +508,7 @@ pub mod foo { inst.func_wrap( "list-u64-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u64_ret(host); Ok((r,)) }, @@ -507,7 +516,7 @@ pub mod foo { inst.func_wrap( "list-s8-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s8_ret(host); Ok((r,)) }, @@ -515,7 +524,7 @@ pub mod foo { inst.func_wrap( "list-s16-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s16_ret(host); Ok((r,)) }, @@ -523,7 +532,7 @@ pub mod foo { inst.func_wrap( "list-s32-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s32_ret(host); Ok((r,)) }, @@ -531,7 +540,7 @@ pub mod foo { inst.func_wrap( "list-s64-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s64_ret(host); Ok((r,)) }, @@ -539,7 +548,7 @@ pub mod foo { inst.func_wrap( "list-float32-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_float32_ret(host); Ok((r,)) }, @@ -547,7 +556,7 @@ pub mod foo { inst.func_wrap( "list-float64-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_float64_ret(host); Ok((r,)) }, @@ -558,7 +567,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec<(u8, i8)>,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_list(host, arg0); Ok((r,)) }, @@ -575,7 +584,7 @@ pub mod foo { >, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::string_list_arg(host, arg0); Ok(r) }, @@ -583,7 +592,7 @@ pub mod foo { inst.func_wrap( "string-list-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::string_list_ret(host); Ok((r,)) }, @@ -600,7 +609,7 @@ pub mod foo { >, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_string_list(host, arg0); Ok((r,)) }, @@ -617,7 +626,7 @@ pub mod foo { >, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::string_list(host, arg0); Ok((r,)) }, @@ -628,7 +637,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_list(host, arg0); Ok((r,)) }, @@ -639,7 +648,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_list_reverse(host, arg0); Ok((r,)) }, @@ -650,7 +659,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::variant_list(host, arg0); Ok((r,)) }, @@ -661,13 +670,183 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (LoadStoreAllSizes,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::load_store_everything(host, arg0); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn list_u8_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u8_param(*self, x) + } + fn list_u16_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u16_param(*self, x) + } + fn list_u32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u32_param(*self, x) + } + fn list_u64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u64_param(*self, x) + } + fn list_s8_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s8_param(*self, x) + } + fn list_s16_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s16_param(*self, x) + } + fn list_s32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s32_param(*self, x) + } + fn list_s64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s64_param(*self, x) + } + fn list_float32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_float32_param(*self, x) + } + fn list_float64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_float64_param(*self, x) + } + fn list_u8_ret(&mut self) -> wasmtime::component::__internal::Vec { + Host::list_u8_ret(*self) + } + fn list_u16_ret(&mut self) -> wasmtime::component::__internal::Vec { + Host::list_u16_ret(*self) + } + fn list_u32_ret(&mut self) -> wasmtime::component::__internal::Vec { + Host::list_u32_ret(*self) + } + fn list_u64_ret(&mut self) -> wasmtime::component::__internal::Vec { + Host::list_u64_ret(*self) + } + fn list_s8_ret(&mut self) -> wasmtime::component::__internal::Vec { + Host::list_s8_ret(*self) + } + fn list_s16_ret(&mut self) -> wasmtime::component::__internal::Vec { + Host::list_s16_ret(*self) + } + fn list_s32_ret(&mut self) -> wasmtime::component::__internal::Vec { + Host::list_s32_ret(*self) + } + fn list_s64_ret(&mut self) -> wasmtime::component::__internal::Vec { + Host::list_s64_ret(*self) + } + fn list_float32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_float32_ret(*self) + } + fn list_float64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_float64_ret(*self) + } + fn tuple_list( + &mut self, + x: wasmtime::component::__internal::Vec<(u8, i8)>, + ) -> wasmtime::component::__internal::Vec<(i64, u32)> { + Host::tuple_list(*self, x) + } + fn string_list_arg( + &mut self, + a: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ) -> () { + Host::string_list_arg(*self, a) + } + fn string_list_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + > { + Host::string_list_ret(*self) + } + fn tuple_string_list( + &mut self, + x: wasmtime::component::__internal::Vec< + (u8, wasmtime::component::__internal::String), + >, + ) -> wasmtime::component::__internal::Vec< + (wasmtime::component::__internal::String, u8), + > { + Host::tuple_string_list(*self, x) + } + fn string_list( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + > { + Host::string_list(*self, x) + } + fn record_list( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::record_list(*self, x) + } + fn record_list_reverse( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::record_list_reverse(*self, x) + } + fn variant_list( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::variant_list(*self, x) + } + fn load_store_everything( + &mut self, + a: LoadStoreAllSizes, + ) -> LoadStoreAllSizes { + Host::load_store_everything(*self, a) + } + } } } } diff --git a/crates/component-macro/tests/expanded/lists_async.rs b/crates/component-macro/tests/expanded/lists_async.rs index 94037381a11..9692a90682a 100644 --- a/crates/component-macro/tests/expanded/lists_async.rs +++ b/crates/component-macro/tests/expanded/lists_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::lists::Host + Send, T: Send, + U: foo::foo::lists::Host + Send, { foo::foo::lists::add_to_linker(linker, get)?; Ok(()) @@ -253,7 +253,7 @@ pub mod foo { ); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn list_u8_param( &mut self, x: wasmtime::component::__internal::Vec, @@ -372,13 +372,24 @@ pub mod foo { a: LoadStoreAllSizes, ) -> LoadStoreAllSizes; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/lists")?; inst.func_wrap_async( @@ -387,7 +398,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u8_param(host, arg0).await; Ok(r) }), @@ -398,7 +409,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u16_param(host, arg0).await; Ok(r) }), @@ -409,7 +420,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u32_param(host, arg0).await; Ok(r) }), @@ -420,7 +431,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u64_param(host, arg0).await; Ok(r) }), @@ -431,7 +442,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s8_param(host, arg0).await; Ok(r) }), @@ -442,7 +453,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s16_param(host, arg0).await; Ok(r) }), @@ -453,7 +464,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s32_param(host, arg0).await; Ok(r) }), @@ -464,7 +475,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s64_param(host, arg0).await; Ok(r) }), @@ -475,7 +486,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_float32_param(host, arg0).await; Ok(r) }), @@ -486,7 +497,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_float64_param(host, arg0).await; Ok(r) }), @@ -494,7 +505,7 @@ pub mod foo { inst.func_wrap_async( "list-u8-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u8_ret(host).await; Ok((r,)) }), @@ -502,7 +513,7 @@ pub mod foo { inst.func_wrap_async( "list-u16-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u16_ret(host).await; Ok((r,)) }), @@ -510,7 +521,7 @@ pub mod foo { inst.func_wrap_async( "list-u32-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u32_ret(host).await; Ok((r,)) }), @@ -518,7 +529,7 @@ pub mod foo { inst.func_wrap_async( "list-u64-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_u64_ret(host).await; Ok((r,)) }), @@ -526,7 +537,7 @@ pub mod foo { inst.func_wrap_async( "list-s8-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s8_ret(host).await; Ok((r,)) }), @@ -534,7 +545,7 @@ pub mod foo { inst.func_wrap_async( "list-s16-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s16_ret(host).await; Ok((r,)) }), @@ -542,7 +553,7 @@ pub mod foo { inst.func_wrap_async( "list-s32-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s32_ret(host).await; Ok((r,)) }), @@ -550,7 +561,7 @@ pub mod foo { inst.func_wrap_async( "list-s64-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_s64_ret(host).await; Ok((r,)) }), @@ -558,7 +569,7 @@ pub mod foo { inst.func_wrap_async( "list-float32-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_float32_ret(host).await; Ok((r,)) }), @@ -566,7 +577,7 @@ pub mod foo { inst.func_wrap_async( "list-float64-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_float64_ret(host).await; Ok((r,)) }), @@ -577,7 +588,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec<(u8, i8)>,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_list(host, arg0).await; Ok((r,)) }), @@ -594,7 +605,7 @@ pub mod foo { >, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::string_list_arg(host, arg0).await; Ok(r) }), @@ -602,7 +613,7 @@ pub mod foo { inst.func_wrap_async( "string-list-ret", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::string_list_ret(host).await; Ok((r,)) }), @@ -619,7 +630,7 @@ pub mod foo { >, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_string_list(host, arg0).await; Ok((r,)) }), @@ -636,7 +647,7 @@ pub mod foo { >, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::string_list(host, arg0).await; Ok((r,)) }), @@ -647,7 +658,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_list(host, arg0).await; Ok((r,)) }), @@ -658,7 +669,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_list_reverse(host, arg0).await; Ok((r,)) }), @@ -669,7 +680,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::variant_list(host, arg0).await; Ok((r,)) }), @@ -680,13 +691,201 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (LoadStoreAllSizes,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::load_store_everything(host, arg0).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn list_u8_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u8_param(*self, x).await + } + async fn list_u16_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u16_param(*self, x).await + } + async fn list_u32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u32_param(*self, x).await + } + async fn list_u64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_u64_param(*self, x).await + } + async fn list_s8_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s8_param(*self, x).await + } + async fn list_s16_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s16_param(*self, x).await + } + async fn list_s32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s32_param(*self, x).await + } + async fn list_s64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_s64_param(*self, x).await + } + async fn list_float32_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_float32_param(*self, x).await + } + async fn list_float64_param( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> () { + Host::list_float64_param(*self, x).await + } + async fn list_u8_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_u8_ret(*self).await + } + async fn list_u16_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_u16_ret(*self).await + } + async fn list_u32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_u32_ret(*self).await + } + async fn list_u64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_u64_ret(*self).await + } + async fn list_s8_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_s8_ret(*self).await + } + async fn list_s16_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_s16_ret(*self).await + } + async fn list_s32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_s32_ret(*self).await + } + async fn list_s64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_s64_ret(*self).await + } + async fn list_float32_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_float32_ret(*self).await + } + async fn list_float64_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::list_float64_ret(*self).await + } + async fn tuple_list( + &mut self, + x: wasmtime::component::__internal::Vec<(u8, i8)>, + ) -> wasmtime::component::__internal::Vec<(i64, u32)> { + Host::tuple_list(*self, x).await + } + async fn string_list_arg( + &mut self, + a: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ) -> () { + Host::string_list_arg(*self, a).await + } + async fn string_list_ret( + &mut self, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + > { + Host::string_list_ret(*self).await + } + async fn tuple_string_list( + &mut self, + x: wasmtime::component::__internal::Vec< + (u8, wasmtime::component::__internal::String), + >, + ) -> wasmtime::component::__internal::Vec< + (wasmtime::component::__internal::String, u8), + > { + Host::tuple_string_list(*self, x).await + } + async fn string_list( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + >, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::String, + > { + Host::string_list(*self, x).await + } + async fn record_list( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::record_list(*self, x).await + } + async fn record_list_reverse( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::record_list_reverse(*self, x).await + } + async fn variant_list( + &mut self, + x: wasmtime::component::__internal::Vec, + ) -> wasmtime::component::__internal::Vec { + Host::variant_list(*self, x).await + } + async fn load_store_everything( + &mut self, + a: LoadStoreAllSizes, + ) -> LoadStoreAllSizes { + Host::load_store_everything(*self, a).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/many-arguments.rs b/crates/component-macro/tests/expanded/many-arguments.rs index e3b55ac5778..0d738e7aeba 100644 --- a/crates/component-macro/tests/expanded/many-arguments.rs +++ b/crates/component-macro/tests/expanded/many-arguments.rs @@ -176,13 +176,22 @@ pub mod foo { ) -> (); fn big_argument(&mut self, x: BigStruct) -> (); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/manyarg")?; inst.func_wrap( "many-args", @@ -224,7 +233,7 @@ pub mod foo { u64, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::many_args( host, arg0, @@ -253,13 +262,66 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (BigStruct,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::big_argument(host, arg0); Ok(r) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn many_args( + &mut self, + a1: u64, + a2: u64, + a3: u64, + a4: u64, + a5: u64, + a6: u64, + a7: u64, + a8: u64, + a9: u64, + a10: u64, + a11: u64, + a12: u64, + a13: u64, + a14: u64, + a15: u64, + a16: u64, + ) -> () { + Host::many_args( + *self, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + ) + } + fn big_argument(&mut self, x: BigStruct) -> () { + Host::big_argument(*self, x) + } + } } } } diff --git a/crates/component-macro/tests/expanded/many-arguments_async.rs b/crates/component-macro/tests/expanded/many-arguments_async.rs index 93d390d13b4..fa03d7a4766 100644 --- a/crates/component-macro/tests/expanded/many-arguments_async.rs +++ b/crates/component-macro/tests/expanded/many-arguments_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::manyarg::Host + Send, T: Send, + U: foo::foo::manyarg::Host + Send, { foo::foo::manyarg::add_to_linker(linker, get)?; Ok(()) @@ -156,7 +156,7 @@ pub mod foo { ); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn many_args( &mut self, a1: u64, @@ -178,13 +178,24 @@ pub mod foo { ) -> (); async fn big_argument(&mut self, x: BigStruct) -> (); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/manyarg")?; inst.func_wrap_async( @@ -227,7 +238,7 @@ pub mod foo { u64, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::many_args( host, arg0, @@ -257,13 +268,69 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (BigStruct,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::big_argument(host, arg0).await; Ok(r) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn many_args( + &mut self, + a1: u64, + a2: u64, + a3: u64, + a4: u64, + a5: u64, + a6: u64, + a7: u64, + a8: u64, + a9: u64, + a10: u64, + a11: u64, + a12: u64, + a13: u64, + a14: u64, + a15: u64, + a16: u64, + ) -> () { + Host::many_args( + *self, + a1, + a2, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, + ) + .await + } + async fn big_argument(&mut self, x: BigStruct) -> () { + Host::big_argument(*self, x).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/multi-return.rs b/crates/component-macro/tests/expanded/multi-return.rs index e46103e572d..abfb3c59b68 100644 --- a/crates/component-macro/tests/expanded/multi-return.rs +++ b/crates/component-macro/tests/expanded/multi-return.rs @@ -80,18 +80,27 @@ pub mod foo { fn mrd(&mut self) -> u32; fn mre(&mut self) -> (u32, f32); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/multi-return")?; inst.func_wrap( "mra", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mra(host); Ok(r) }, @@ -99,7 +108,7 @@ pub mod foo { inst.func_wrap( "mrb", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mrb(host); Ok(r) }, @@ -107,7 +116,7 @@ pub mod foo { inst.func_wrap( "mrc", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mrc(host); Ok((r,)) }, @@ -115,7 +124,7 @@ pub mod foo { inst.func_wrap( "mrd", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mrd(host); Ok((r,)) }, @@ -123,13 +132,39 @@ pub mod foo { inst.func_wrap( "mre", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mre(host); Ok(r) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn mra(&mut self) -> () { + Host::mra(*self) + } + fn mrb(&mut self) -> () { + Host::mrb(*self) + } + fn mrc(&mut self) -> u32 { + Host::mrc(*self) + } + fn mrd(&mut self) -> u32 { + Host::mrd(*self) + } + fn mre(&mut self) -> (u32, f32) { + Host::mre(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/multi-return_async.rs b/crates/component-macro/tests/expanded/multi-return_async.rs index f915a27f0fc..650b4f2ee67 100644 --- a/crates/component-macro/tests/expanded/multi-return_async.rs +++ b/crates/component-macro/tests/expanded/multi-return_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::multi_return::Host + Send, T: Send, + U: foo::foo::multi_return::Host + Send, { foo::foo::multi_return::add_to_linker(linker, get)?; Ok(()) @@ -75,26 +75,37 @@ pub mod foo { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn mra(&mut self) -> (); async fn mrb(&mut self) -> (); async fn mrc(&mut self) -> u32; async fn mrd(&mut self) -> u32; async fn mre(&mut self) -> (u32, f32); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/multi-return")?; inst.func_wrap_async( "mra", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mra(host).await; Ok(r) }), @@ -102,7 +113,7 @@ pub mod foo { inst.func_wrap_async( "mrb", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mrb(host).await; Ok(r) }), @@ -110,7 +121,7 @@ pub mod foo { inst.func_wrap_async( "mrc", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mrc(host).await; Ok((r,)) }), @@ -118,7 +129,7 @@ pub mod foo { inst.func_wrap_async( "mrd", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mrd(host).await; Ok((r,)) }), @@ -126,13 +137,41 @@ pub mod foo { inst.func_wrap_async( "mre", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::mre(host).await; Ok(r) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn mra(&mut self) -> () { + Host::mra(*self).await + } + async fn mrb(&mut self) -> () { + Host::mrb(*self).await + } + async fn mrc(&mut self) -> u32 { + Host::mrc(*self).await + } + async fn mrd(&mut self) -> u32 { + Host::mrd(*self).await + } + async fn mre(&mut self) -> (u32, f32) { + Host::mre(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/multiversion.rs b/crates/component-macro/tests/expanded/multiversion.rs index 7c456bed43c..72bed565d47 100644 --- a/crates/component-macro/tests/expanded/multiversion.rs +++ b/crates/component-macro/tests/expanded/multiversion.rs @@ -86,24 +86,47 @@ pub mod my { pub trait Host { fn x(&mut self) -> (); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("my:dep/a@0.1.0")?; inst.func_wrap( "x", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::x(host); Ok(r) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn x(&mut self) -> () { + Host::x(*self) + } + } } } pub mod dep0_2_0 { @@ -114,24 +137,47 @@ pub mod my { pub trait Host { fn x(&mut self) -> (); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("my:dep/a@0.2.0")?; inst.func_wrap( "x", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::x(host); Ok(r) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn x(&mut self) -> () { + Host::x(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/multiversion_async.rs b/crates/component-macro/tests/expanded/multiversion_async.rs index e0503b87cee..5c3ab925d95 100644 --- a/crates/component-macro/tests/expanded/multiversion_async.rs +++ b/crates/component-macro/tests/expanded/multiversion_async.rs @@ -11,8 +11,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: my::dep0_1_0::a::Host + my::dep0_2_0::a::Host + Send, T: Send, + U: my::dep0_1_0::a::Host + my::dep0_2_0::a::Host + Send, { my::dep0_1_0::a::add_to_linker(linker, get)?; my::dep0_2_0::a::add_to_linker(linker, get)?; @@ -85,28 +85,55 @@ pub mod my { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn x(&mut self) -> (); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("my:dep/a@0.1.0")?; inst.func_wrap_async( "x", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::x(host).await; Ok(r) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn x(&mut self) -> () { + Host::x(*self).await + } + } } } pub mod dep0_2_0 { @@ -115,28 +142,55 @@ pub mod my { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn x(&mut self) -> (); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("my:dep/a@0.2.0")?; inst.func_wrap_async( "x", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::x(host).await; Ok(r) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn x(&mut self) -> () { + Host::x(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/records.rs b/crates/component-macro/tests/expanded/records.rs index 3ad72c37162..6a8d8016eb9 100644 --- a/crates/component-macro/tests/expanded/records.rs +++ b/crates/component-macro/tests/expanded/records.rs @@ -232,13 +232,22 @@ pub mod foo { fn aggregate_result(&mut self) -> Aggregates; fn typedef_inout(&mut self, e: TupleTypedef2) -> i32; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/records")?; inst.func_wrap( "tuple-arg", @@ -246,7 +255,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): ((char, u32),)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_arg(host, arg0); Ok(r) }, @@ -254,7 +263,7 @@ pub mod foo { inst.func_wrap( "tuple-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_result(host); Ok((r,)) }, @@ -265,7 +274,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Empty,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::empty_arg(host, arg0); Ok(r) }, @@ -273,7 +282,7 @@ pub mod foo { inst.func_wrap( "empty-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::empty_result(host); Ok((r,)) }, @@ -284,7 +293,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Scalars,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::scalar_arg(host, arg0); Ok(r) }, @@ -292,7 +301,7 @@ pub mod foo { inst.func_wrap( "scalar-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::scalar_result(host); Ok((r,)) }, @@ -303,7 +312,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (ReallyFlags,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::flags_arg(host, arg0); Ok(r) }, @@ -311,7 +320,7 @@ pub mod foo { inst.func_wrap( "flags-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::flags_result(host); Ok((r,)) }, @@ -322,7 +331,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Aggregates,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::aggregate_arg(host, arg0); Ok(r) }, @@ -330,7 +339,7 @@ pub mod foo { inst.func_wrap( "aggregate-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::aggregate_result(host); Ok((r,)) }, @@ -341,13 +350,57 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (TupleTypedef2,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::typedef_inout(host, arg0); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn tuple_arg(&mut self, x: (char, u32)) -> () { + Host::tuple_arg(*self, x) + } + fn tuple_result(&mut self) -> (char, u32) { + Host::tuple_result(*self) + } + fn empty_arg(&mut self, x: Empty) -> () { + Host::empty_arg(*self, x) + } + fn empty_result(&mut self) -> Empty { + Host::empty_result(*self) + } + fn scalar_arg(&mut self, x: Scalars) -> () { + Host::scalar_arg(*self, x) + } + fn scalar_result(&mut self) -> Scalars { + Host::scalar_result(*self) + } + fn flags_arg(&mut self, x: ReallyFlags) -> () { + Host::flags_arg(*self, x) + } + fn flags_result(&mut self) -> ReallyFlags { + Host::flags_result(*self) + } + fn aggregate_arg(&mut self, x: Aggregates) -> () { + Host::aggregate_arg(*self, x) + } + fn aggregate_result(&mut self) -> Aggregates { + Host::aggregate_result(*self) + } + fn typedef_inout(&mut self, e: TupleTypedef2) -> i32 { + Host::typedef_inout(*self, e) + } + } } } } diff --git a/crates/component-macro/tests/expanded/records_async.rs b/crates/component-macro/tests/expanded/records_async.rs index d69a7d13d31..cc3e1e029b3 100644 --- a/crates/component-macro/tests/expanded/records_async.rs +++ b/crates/component-macro/tests/expanded/records_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::records::Host + Send, T: Send, + U: foo::foo::records::Host + Send, { foo::foo::records::add_to_linker(linker, get)?; Ok(()) @@ -221,7 +221,7 @@ pub mod foo { ); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn tuple_arg(&mut self, x: (char, u32)) -> (); async fn tuple_result(&mut self) -> (char, u32); async fn empty_arg(&mut self, x: Empty) -> (); @@ -234,13 +234,24 @@ pub mod foo { async fn aggregate_result(&mut self) -> Aggregates; async fn typedef_inout(&mut self, e: TupleTypedef2) -> i32; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/records")?; inst.func_wrap_async( @@ -249,7 +260,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): ((char, u32),)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_arg(host, arg0).await; Ok(r) }), @@ -257,7 +268,7 @@ pub mod foo { inst.func_wrap_async( "tuple-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_result(host).await; Ok((r,)) }), @@ -268,7 +279,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Empty,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::empty_arg(host, arg0).await; Ok(r) }), @@ -276,7 +287,7 @@ pub mod foo { inst.func_wrap_async( "empty-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::empty_result(host).await; Ok((r,)) }), @@ -287,7 +298,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Scalars,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::scalar_arg(host, arg0).await; Ok(r) }), @@ -295,7 +306,7 @@ pub mod foo { inst.func_wrap_async( "scalar-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::scalar_result(host).await; Ok((r,)) }), @@ -306,7 +317,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (ReallyFlags,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::flags_arg(host, arg0).await; Ok(r) }), @@ -314,7 +325,7 @@ pub mod foo { inst.func_wrap_async( "flags-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::flags_result(host).await; Ok((r,)) }), @@ -325,7 +336,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Aggregates,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::aggregate_arg(host, arg0).await; Ok(r) }), @@ -333,7 +344,7 @@ pub mod foo { inst.func_wrap_async( "aggregate-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::aggregate_result(host).await; Ok((r,)) }), @@ -344,13 +355,59 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (TupleTypedef2,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::typedef_inout(host, arg0).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn tuple_arg(&mut self, x: (char, u32)) -> () { + Host::tuple_arg(*self, x).await + } + async fn tuple_result(&mut self) -> (char, u32) { + Host::tuple_result(*self).await + } + async fn empty_arg(&mut self, x: Empty) -> () { + Host::empty_arg(*self, x).await + } + async fn empty_result(&mut self) -> Empty { + Host::empty_result(*self).await + } + async fn scalar_arg(&mut self, x: Scalars) -> () { + Host::scalar_arg(*self, x).await + } + async fn scalar_result(&mut self) -> Scalars { + Host::scalar_result(*self).await + } + async fn flags_arg(&mut self, x: ReallyFlags) -> () { + Host::flags_arg(*self, x).await + } + async fn flags_result(&mut self) -> ReallyFlags { + Host::flags_result(*self).await + } + async fn aggregate_arg(&mut self, x: Aggregates) -> () { + Host::aggregate_arg(*self, x).await + } + async fn aggregate_result(&mut self) -> Aggregates { + Host::aggregate_result(*self).await + } + async fn typedef_inout(&mut self, e: TupleTypedef2) -> i32 { + Host::typedef_inout(*self, e).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/rename.rs b/crates/component-macro/tests/expanded/rename.rs index d571b8a2b7d..cb413829ecf 100644 --- a/crates/component-macro/tests/expanded/rename.rs +++ b/crates/component-macro/tests/expanded/rename.rs @@ -66,6 +66,25 @@ pub mod foo { assert!(4 == < Thing as wasmtime::component::ComponentType >::ALIGN32); }; pub trait Host {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { + let mut inst = linker.instance("foo:foo/green")?; + Ok(()) + } pub fn add_to_linker( linker: &mut wasmtime::component::Linker, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, @@ -73,9 +92,9 @@ pub mod foo { where U: Host, { - let mut inst = linker.instance("foo:foo/green")?; - Ok(()) + add_to_linker_get_host(linker, get) } + impl<_T: Host + ?Sized> Host for &mut _T {} } #[allow(clippy::all)] pub mod red { @@ -89,24 +108,47 @@ pub mod foo { pub trait Host { fn foo(&mut self) -> Thing; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/red")?; inst.func_wrap( "foo", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::foo(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn foo(&mut self) -> Thing { + Host::foo(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/rename_async.rs b/crates/component-macro/tests/expanded/rename_async.rs index 282d55ddc09..6263ce3455b 100644 --- a/crates/component-macro/tests/expanded/rename_async.rs +++ b/crates/component-macro/tests/expanded/rename_async.rs @@ -8,8 +8,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::green::Host + foo::foo::red::Host + Send, T: Send, + U: foo::foo::green::Host + foo::foo::red::Host + Send, { foo::foo::green::add_to_linker(linker, get)?; foo::foo::red::add_to_linker(linker, get)?; @@ -67,18 +67,41 @@ pub mod foo { assert!(4 == < Thing as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host {} - pub fn add_to_linker( + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/green")?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } #[allow(clippy::all)] pub mod red { @@ -90,28 +113,55 @@ pub mod foo { assert!(4 == < Thing as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn foo(&mut self) -> Thing; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/red")?; inst.func_wrap_async( "foo", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::foo(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn foo(&mut self) -> Thing { + Host::foo(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/resources-export.rs b/crates/component-macro/tests/expanded/resources-export.rs index 9e24f76cb8e..ff5946cee7b 100644 --- a/crates/component-macro/tests/expanded/resources-export.rs +++ b/crates/component-macro/tests/expanded/resources-export.rs @@ -130,27 +130,54 @@ pub mod foo { rep: wasmtime::component::Resource, ) -> wasmtime::Result<()>; } + impl<_T: HostY + ?Sized> HostY for &mut _T { + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostY::drop(*self, rep) + } + } pub trait Host: HostY {} - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/transitive-import")?; inst.resource( "y", wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostY::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/resources-export_async.rs b/crates/component-macro/tests/expanded/resources-export_async.rs index cb2c71b4be6..1c6756ae56e 100644 --- a/crates/component-macro/tests/expanded/resources-export_async.rs +++ b/crates/component-macro/tests/expanded/resources-export_async.rs @@ -13,8 +13,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::transitive_import::Host + Send, T: Send, + U: foo::foo::transitive_import::Host + Send, { foo::foo::transitive_import::add_to_linker(linker, get)?; Ok(()) @@ -133,14 +133,34 @@ pub mod foo { ) -> wasmtime::Result<()>; } #[wasmtime::component::__internal::async_trait] - pub trait Host: HostY {} - pub fn add_to_linker( + impl<_T: HostY + ?Sized + Send> HostY for &mut _T { + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostY::drop(*self, rep) + } + } + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send + HostY {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/transitive-import")?; inst.resource( @@ -148,13 +168,25 @@ pub mod foo { wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostY::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/resources-import.rs b/crates/component-macro/tests/expanded/resources-import.rs index 5388a8c006f..3b66536ff01 100644 --- a/crates/component-macro/tests/expanded/resources-import.rs +++ b/crates/component-macro/tests/expanded/resources-import.rs @@ -8,6 +8,23 @@ pub trait HostWorldResource { rep: wasmtime::component::Resource, ) -> wasmtime::Result<()>; } +impl<_T: HostWorldResource + ?Sized> HostWorldResource for &mut _T { + fn new(&mut self) -> wasmtime::component::Resource { + HostWorldResource::new(*self) + } + fn foo(&mut self, self_: wasmtime::component::Resource) -> () { + HostWorldResource::foo(*self, self_) + } + fn static_foo(&mut self) -> () { + HostWorldResource::static_foo(*self) + } + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostWorldResource::drop(*self, rep) + } +} pub struct TheWorld { interface1: exports::foo::foo::uses_resource_transitively::Guest, some_world_func2: wasmtime::component::Func, @@ -15,36 +32,31 @@ pub struct TheWorld { pub trait TheWorldImports: HostWorldResource { fn some_world_func(&mut self) -> wasmtime::component::Resource; } +pub trait TheWorldImportsGetHost< + T, +>: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: TheWorldImports; +} +impl TheWorldImportsGetHost for F +where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: TheWorldImports, +{ + type Host = O; +} +impl<_T: TheWorldImports + ?Sized> TheWorldImports for &mut _T { + fn some_world_func(&mut self) -> wasmtime::component::Resource { + TheWorldImports::some_world_func(*self) + } +} const _: () = { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; impl TheWorld { - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> - where - U: foo::foo::resources::Host + foo::foo::long_use_chain1::Host - + foo::foo::long_use_chain2::Host + foo::foo::long_use_chain3::Host - + foo::foo::long_use_chain4::Host - + foo::foo::transitive_interface_with_resource::Host + TheWorldImports, - { - foo::foo::resources::add_to_linker(linker, get)?; - foo::foo::long_use_chain1::add_to_linker(linker, get)?; - foo::foo::long_use_chain2::add_to_linker(linker, get)?; - foo::foo::long_use_chain3::add_to_linker(linker, get)?; - foo::foo::long_use_chain4::add_to_linker(linker, get)?; - foo::foo::transitive_interface_with_resource::add_to_linker(linker, get)?; - Self::add_root_to_linker(linker, get)?; - Ok(()) - } - pub fn add_root_to_linker( + pub fn add_to_linker_imports_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> - where - U: TheWorldImports, - { + host_getter: impl for<'a> TheWorldImportsGetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut linker = linker.root(); linker .resource( @@ -52,7 +64,7 @@ const _: () = { wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostWorldResource::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, @@ -61,7 +73,7 @@ const _: () = { .func_wrap( "[constructor]world-resource", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostWorldResource::new(host); Ok((r,)) }, @@ -73,7 +85,7 @@ const _: () = { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::Resource,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostWorldResource::foo(host, arg0); Ok(r) }, @@ -82,7 +94,7 @@ const _: () = { .func_wrap( "[static]world-resource.static-foo", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostWorldResource::static_foo(host); Ok(r) }, @@ -91,13 +103,32 @@ const _: () = { .func_wrap( "some-world-func", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = TheWorldImports::some_world_func(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: foo::foo::resources::Host + foo::foo::long_use_chain1::Host + + foo::foo::long_use_chain2::Host + foo::foo::long_use_chain3::Host + + foo::foo::long_use_chain4::Host + + foo::foo::transitive_interface_with_resource::Host + TheWorldImports, + { + Self::add_to_linker_imports_get_host(linker, get)?; + foo::foo::resources::add_to_linker(linker, get)?; + foo::foo::long_use_chain1::add_to_linker(linker, get)?; + foo::foo::long_use_chain2::add_to_linker(linker, get)?; + foo::foo::long_use_chain3::add_to_linker(linker, get)?; + foo::foo::long_use_chain4::add_to_linker(linker, get)?; + foo::foo::transitive_interface_with_resource::add_to_linker(linker, get)?; + Ok(()) + } /// Instantiates the provided `module` using the specified /// parameters, wrapping up the result in a structure that /// translates between wasm and the host. @@ -191,6 +222,26 @@ pub mod foo { rep: wasmtime::component::Resource, ) -> wasmtime::Result<()>; } + impl<_T: HostBar + ?Sized> HostBar for &mut _T { + fn new(&mut self) -> wasmtime::component::Resource { + HostBar::new(*self) + } + fn static_a(&mut self) -> u32 { + HostBar::static_a(*self) + } + fn method_a( + &mut self, + self_: wasmtime::component::Resource, + ) -> u32 { + HostBar::method_a(*self, self_) + } + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostBar::drop(*self, rep) + } + } #[derive(wasmtime::component::ComponentType)] #[derive(wasmtime::component::Lift)] #[derive(wasmtime::component::Lower)] @@ -306,20 +357,29 @@ pub mod foo { fn record_result(&mut self) -> NestedOwn; fn func_with_handle_typedef(&mut self, x: SomeHandle) -> (); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/resources")?; inst.resource( "bar", wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostBar::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, @@ -327,7 +387,7 @@ pub mod foo { inst.func_wrap( "[constructor]bar", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostBar::new(host); Ok((r,)) }, @@ -335,7 +395,7 @@ pub mod foo { inst.func_wrap( "[static]bar.static-a", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostBar::static_a(host); Ok((r,)) }, @@ -346,7 +406,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::Resource,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostBar::method_a(host, arg0); Ok((r,)) }, @@ -357,7 +417,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::Resource,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bar_own_arg(host, arg0); Ok(r) }, @@ -368,7 +428,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::Resource,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bar_borrow_arg(host, arg0); Ok(r) }, @@ -376,7 +436,7 @@ pub mod foo { inst.func_wrap( "bar-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bar_result(host); Ok((r,)) }, @@ -387,7 +447,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): ((wasmtime::component::Resource, u32),)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_own_arg(host, arg0); Ok(r) }, @@ -398,7 +458,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): ((wasmtime::component::Resource, u32),)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_borrow_arg(host, arg0); Ok(r) }, @@ -406,7 +466,7 @@ pub mod foo { inst.func_wrap( "tuple-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_result(host); Ok((r,)) }, @@ -417,7 +477,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Option>,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_own_arg(host, arg0); Ok(r) }, @@ -428,7 +488,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Option>,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_borrow_arg(host, arg0); Ok(r) }, @@ -436,7 +496,7 @@ pub mod foo { inst.func_wrap( "option-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_result(host); Ok((r,)) }, @@ -447,7 +507,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Result, ()>,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_own_arg(host, arg0); Ok(r) }, @@ -458,7 +518,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Result, ()>,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_borrow_arg(host, arg0); Ok(r) }, @@ -466,7 +526,7 @@ pub mod foo { inst.func_wrap( "result-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_result(host); Ok((r,)) }, @@ -483,7 +543,7 @@ pub mod foo { >, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_own_arg(host, arg0); Ok(r) }, @@ -500,7 +560,7 @@ pub mod foo { >, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_borrow_arg(host, arg0); Ok(r) }, @@ -508,7 +568,7 @@ pub mod foo { inst.func_wrap( "list-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_result(host); Ok((r,)) }, @@ -519,7 +579,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (NestedOwn,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_own_arg(host, arg0); Ok(r) }, @@ -530,7 +590,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (NestedBorrow,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_borrow_arg(host, arg0); Ok(r) }, @@ -538,7 +598,7 @@ pub mod foo { inst.func_wrap( "record-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_result(host); Ok((r,)) }, @@ -549,13 +609,120 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (SomeHandle,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::func_with_handle_typedef(host, arg0); Ok(r) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn bar_own_arg(&mut self, x: wasmtime::component::Resource) -> () { + Host::bar_own_arg(*self, x) + } + fn bar_borrow_arg( + &mut self, + x: wasmtime::component::Resource, + ) -> () { + Host::bar_borrow_arg(*self, x) + } + fn bar_result(&mut self) -> wasmtime::component::Resource { + Host::bar_result(*self) + } + fn tuple_own_arg( + &mut self, + x: (wasmtime::component::Resource, u32), + ) -> () { + Host::tuple_own_arg(*self, x) + } + fn tuple_borrow_arg( + &mut self, + x: (wasmtime::component::Resource, u32), + ) -> () { + Host::tuple_borrow_arg(*self, x) + } + fn tuple_result(&mut self) -> (wasmtime::component::Resource, u32) { + Host::tuple_result(*self) + } + fn option_own_arg( + &mut self, + x: Option>, + ) -> () { + Host::option_own_arg(*self, x) + } + fn option_borrow_arg( + &mut self, + x: Option>, + ) -> () { + Host::option_borrow_arg(*self, x) + } + fn option_result( + &mut self, + ) -> Option> { + Host::option_result(*self) + } + fn result_own_arg( + &mut self, + x: Result, ()>, + ) -> () { + Host::result_own_arg(*self, x) + } + fn result_borrow_arg( + &mut self, + x: Result, ()>, + ) -> () { + Host::result_borrow_arg(*self, x) + } + fn result_result( + &mut self, + ) -> Result, ()> { + Host::result_result(*self) + } + fn list_own_arg( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + ) -> () { + Host::list_own_arg(*self, x) + } + fn list_borrow_arg( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + ) -> () { + Host::list_borrow_arg(*self, x) + } + fn list_result( + &mut self, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + > { + Host::list_result(*self) + } + fn record_own_arg(&mut self, x: NestedOwn) -> () { + Host::record_own_arg(*self, x) + } + fn record_borrow_arg(&mut self, x: NestedBorrow) -> () { + Host::record_borrow_arg(*self, x) + } + fn record_result(&mut self) -> NestedOwn { + Host::record_result(*self) + } + fn func_with_handle_typedef(&mut self, x: SomeHandle) -> () { + Host::func_with_handle_typedef(*self, x) + } + } } #[allow(clippy::all)] pub mod long_use_chain1 { @@ -568,27 +735,54 @@ pub mod foo { rep: wasmtime::component::Resource, ) -> wasmtime::Result<()>; } + impl<_T: HostA + ?Sized> HostA for &mut _T { + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostA::drop(*self, rep) + } + } pub trait Host: HostA {} - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/long-use-chain1")?; inst.resource( "a", wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostA::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T {} } #[allow(clippy::all)] pub mod long_use_chain2 { @@ -596,6 +790,25 @@ pub mod foo { use wasmtime::component::__internal::anyhow; pub type A = super::super::super::foo::foo::long_use_chain1::A; pub trait Host {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { + let mut inst = linker.instance("foo:foo/long-use-chain2")?; + Ok(()) + } pub fn add_to_linker( linker: &mut wasmtime::component::Linker, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, @@ -603,9 +816,9 @@ pub mod foo { where U: Host, { - let mut inst = linker.instance("foo:foo/long-use-chain2")?; - Ok(()) + add_to_linker_get_host(linker, get) } + impl<_T: Host + ?Sized> Host for &mut _T {} } #[allow(clippy::all)] pub mod long_use_chain3 { @@ -613,6 +826,25 @@ pub mod foo { use wasmtime::component::__internal::anyhow; pub type A = super::super::super::foo::foo::long_use_chain2::A; pub trait Host {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { + let mut inst = linker.instance("foo:foo/long-use-chain3")?; + Ok(()) + } pub fn add_to_linker( linker: &mut wasmtime::component::Linker, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, @@ -620,9 +852,9 @@ pub mod foo { where U: Host, { - let mut inst = linker.instance("foo:foo/long-use-chain3")?; - Ok(()) + add_to_linker_get_host(linker, get) } + impl<_T: Host + ?Sized> Host for &mut _T {} } #[allow(clippy::all)] pub mod long_use_chain4 { @@ -632,24 +864,47 @@ pub mod foo { pub trait Host { fn foo(&mut self) -> wasmtime::component::Resource; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/long-use-chain4")?; inst.func_wrap( "foo", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::foo(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn foo(&mut self) -> wasmtime::component::Resource { + Host::foo(*self) + } + } } #[allow(clippy::all)] pub mod transitive_interface_with_resource { @@ -662,14 +917,31 @@ pub mod foo { rep: wasmtime::component::Resource, ) -> wasmtime::Result<()>; } + impl<_T: HostFoo + ?Sized> HostFoo for &mut _T { + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostFoo::drop(*self, rep) + } + } pub trait Host: HostFoo {} - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker .instance("foo:foo/transitive-interface-with-resource")?; inst.resource( @@ -677,13 +949,23 @@ pub mod foo { wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostFoo::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/resources-import_async.rs b/crates/component-macro/tests/expanded/resources-import_async.rs index b783974ef74..9ee7049b51f 100644 --- a/crates/component-macro/tests/expanded/resources-import_async.rs +++ b/crates/component-macro/tests/expanded/resources-import_async.rs @@ -9,45 +9,59 @@ pub trait HostWorldResource { rep: wasmtime::component::Resource, ) -> wasmtime::Result<()>; } +#[wasmtime::component::__internal::async_trait] +impl<_T: HostWorldResource + ?Sized + Send> HostWorldResource for &mut _T { + async fn new(&mut self) -> wasmtime::component::Resource { + HostWorldResource::new(*self).await + } + async fn foo(&mut self, self_: wasmtime::component::Resource) -> () { + HostWorldResource::foo(*self, self_).await + } + async fn static_foo(&mut self) -> () { + HostWorldResource::static_foo(*self).await + } + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostWorldResource::drop(*self, rep) + } +} pub struct TheWorld { interface1: exports::foo::foo::uses_resource_transitively::Guest, some_world_func2: wasmtime::component::Func, } #[wasmtime::component::__internal::async_trait] -pub trait TheWorldImports: HostWorldResource { +pub trait TheWorldImports: Send + HostWorldResource { async fn some_world_func(&mut self) -> wasmtime::component::Resource; } +pub trait TheWorldImportsGetHost< + T, +>: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: TheWorldImports; +} +impl TheWorldImportsGetHost for F +where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: TheWorldImports, +{ + type Host = O; +} +#[wasmtime::component::__internal::async_trait] +impl<_T: TheWorldImports + ?Sized + Send> TheWorldImports for &mut _T { + async fn some_world_func(&mut self) -> wasmtime::component::Resource { + TheWorldImports::some_world_func(*self).await + } +} const _: () = { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; impl TheWorld { - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> - where - U: foo::foo::resources::Host + foo::foo::long_use_chain1::Host - + foo::foo::long_use_chain2::Host + foo::foo::long_use_chain3::Host - + foo::foo::long_use_chain4::Host - + foo::foo::transitive_interface_with_resource::Host + TheWorldImports - + Send, - T: Send, - { - foo::foo::resources::add_to_linker(linker, get)?; - foo::foo::long_use_chain1::add_to_linker(linker, get)?; - foo::foo::long_use_chain2::add_to_linker(linker, get)?; - foo::foo::long_use_chain3::add_to_linker(linker, get)?; - foo::foo::long_use_chain4::add_to_linker(linker, get)?; - foo::foo::transitive_interface_with_resource::add_to_linker(linker, get)?; - Self::add_root_to_linker(linker, get)?; - Ok(()) - } - pub fn add_root_to_linker( + pub fn add_to_linker_imports_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> TheWorldImportsGetHost<&'a mut T>, ) -> wasmtime::Result<()> where - U: TheWorldImports + Send, T: Send, { let mut linker = linker.root(); @@ -57,7 +71,7 @@ const _: () = { wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostWorldResource::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, @@ -66,7 +80,7 @@ const _: () = { .func_wrap_async( "[constructor]world-resource", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostWorldResource::new(host).await; Ok((r,)) }), @@ -78,7 +92,7 @@ const _: () = { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::Resource,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostWorldResource::foo(host, arg0).await; Ok(r) }), @@ -87,7 +101,7 @@ const _: () = { .func_wrap_async( "[static]world-resource.static-foo", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostWorldResource::static_foo(host).await; Ok(r) }), @@ -96,13 +110,34 @@ const _: () = { .func_wrap_async( "some-world-func", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = TheWorldImports::some_world_func(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + T: Send, + U: foo::foo::resources::Host + foo::foo::long_use_chain1::Host + + foo::foo::long_use_chain2::Host + foo::foo::long_use_chain3::Host + + foo::foo::long_use_chain4::Host + + foo::foo::transitive_interface_with_resource::Host + TheWorldImports + + Send, + { + Self::add_to_linker_imports_get_host(linker, get)?; + foo::foo::resources::add_to_linker(linker, get)?; + foo::foo::long_use_chain1::add_to_linker(linker, get)?; + foo::foo::long_use_chain2::add_to_linker(linker, get)?; + foo::foo::long_use_chain3::add_to_linker(linker, get)?; + foo::foo::long_use_chain4::add_to_linker(linker, get)?; + foo::foo::transitive_interface_with_resource::add_to_linker(linker, get)?; + Ok(()) + } /// Instantiates the provided `module` using the specified /// parameters, wrapping up the result in a structure that /// translates between wasm and the host. @@ -203,6 +238,27 @@ pub mod foo { rep: wasmtime::component::Resource, ) -> wasmtime::Result<()>; } + #[wasmtime::component::__internal::async_trait] + impl<_T: HostBar + ?Sized + Send> HostBar for &mut _T { + async fn new(&mut self) -> wasmtime::component::Resource { + HostBar::new(*self).await + } + async fn static_a(&mut self) -> u32 { + HostBar::static_a(*self).await + } + async fn method_a( + &mut self, + self_: wasmtime::component::Resource, + ) -> u32 { + HostBar::method_a(*self, self_).await + } + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostBar::drop(*self, rep) + } + } #[derive(wasmtime::component::ComponentType)] #[derive(wasmtime::component::Lift)] #[derive(wasmtime::component::Lower)] @@ -259,7 +315,7 @@ pub mod foo { ); }; #[wasmtime::component::__internal::async_trait] - pub trait Host: HostBar { + pub trait Host: Send + HostBar { async fn bar_own_arg( &mut self, x: wasmtime::component::Resource, @@ -324,13 +380,24 @@ pub mod foo { async fn record_result(&mut self) -> NestedOwn; async fn func_with_handle_typedef(&mut self, x: SomeHandle) -> (); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/resources")?; inst.resource( @@ -338,7 +405,7 @@ pub mod foo { wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostBar::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, @@ -346,7 +413,7 @@ pub mod foo { inst.func_wrap_async( "[constructor]bar", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostBar::new(host).await; Ok((r,)) }), @@ -354,7 +421,7 @@ pub mod foo { inst.func_wrap_async( "[static]bar.static-a", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostBar::static_a(host).await; Ok((r,)) }), @@ -365,7 +432,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::Resource,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = HostBar::method_a(host, arg0).await; Ok((r,)) }), @@ -376,7 +443,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::Resource,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bar_own_arg(host, arg0).await; Ok(r) }), @@ -387,7 +454,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::Resource,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bar_borrow_arg(host, arg0).await; Ok(r) }), @@ -395,7 +462,7 @@ pub mod foo { inst.func_wrap_async( "bar-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bar_result(host).await; Ok((r,)) }), @@ -406,7 +473,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): ((wasmtime::component::Resource, u32),)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_own_arg(host, arg0).await; Ok(r) }), @@ -417,7 +484,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): ((wasmtime::component::Resource, u32),)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_borrow_arg(host, arg0).await; Ok(r) }), @@ -425,7 +492,7 @@ pub mod foo { inst.func_wrap_async( "tuple-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::tuple_result(host).await; Ok((r,)) }), @@ -436,7 +503,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Option>,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_own_arg(host, arg0).await; Ok(r) }), @@ -447,7 +514,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Option>,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_borrow_arg(host, arg0).await; Ok(r) }), @@ -455,7 +522,7 @@ pub mod foo { inst.func_wrap_async( "option-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_result(host).await; Ok((r,)) }), @@ -466,7 +533,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Result, ()>,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_own_arg(host, arg0).await; Ok(r) }), @@ -477,7 +544,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Result, ()>,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_borrow_arg(host, arg0).await; Ok(r) }), @@ -485,7 +552,7 @@ pub mod foo { inst.func_wrap_async( "result-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_result(host).await; Ok((r,)) }), @@ -502,7 +569,7 @@ pub mod foo { >, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_own_arg(host, arg0).await; Ok(r) }), @@ -519,7 +586,7 @@ pub mod foo { >, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_borrow_arg(host, arg0).await; Ok(r) }), @@ -527,7 +594,7 @@ pub mod foo { inst.func_wrap_async( "list-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::list_result(host).await; Ok((r,)) }), @@ -538,7 +605,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (NestedOwn,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_own_arg(host, arg0).await; Ok(r) }), @@ -549,7 +616,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (NestedBorrow,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_borrow_arg(host, arg0).await; Ok(r) }), @@ -557,7 +624,7 @@ pub mod foo { inst.func_wrap_async( "record-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::record_result(host).await; Ok((r,)) }), @@ -568,13 +635,127 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (SomeHandle,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::func_with_handle_typedef(host, arg0).await; Ok(r) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn bar_own_arg( + &mut self, + x: wasmtime::component::Resource, + ) -> () { + Host::bar_own_arg(*self, x).await + } + async fn bar_borrow_arg( + &mut self, + x: wasmtime::component::Resource, + ) -> () { + Host::bar_borrow_arg(*self, x).await + } + async fn bar_result(&mut self) -> wasmtime::component::Resource { + Host::bar_result(*self).await + } + async fn tuple_own_arg( + &mut self, + x: (wasmtime::component::Resource, u32), + ) -> () { + Host::tuple_own_arg(*self, x).await + } + async fn tuple_borrow_arg( + &mut self, + x: (wasmtime::component::Resource, u32), + ) -> () { + Host::tuple_borrow_arg(*self, x).await + } + async fn tuple_result( + &mut self, + ) -> (wasmtime::component::Resource, u32) { + Host::tuple_result(*self).await + } + async fn option_own_arg( + &mut self, + x: Option>, + ) -> () { + Host::option_own_arg(*self, x).await + } + async fn option_borrow_arg( + &mut self, + x: Option>, + ) -> () { + Host::option_borrow_arg(*self, x).await + } + async fn option_result( + &mut self, + ) -> Option> { + Host::option_result(*self).await + } + async fn result_own_arg( + &mut self, + x: Result, ()>, + ) -> () { + Host::result_own_arg(*self, x).await + } + async fn result_borrow_arg( + &mut self, + x: Result, ()>, + ) -> () { + Host::result_borrow_arg(*self, x).await + } + async fn result_result( + &mut self, + ) -> Result, ()> { + Host::result_result(*self).await + } + async fn list_own_arg( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + ) -> () { + Host::list_own_arg(*self, x).await + } + async fn list_borrow_arg( + &mut self, + x: wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + >, + ) -> () { + Host::list_borrow_arg(*self, x).await + } + async fn list_result( + &mut self, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::Resource, + > { + Host::list_result(*self).await + } + async fn record_own_arg(&mut self, x: NestedOwn) -> () { + Host::record_own_arg(*self, x).await + } + async fn record_borrow_arg(&mut self, x: NestedBorrow) -> () { + Host::record_borrow_arg(*self, x).await + } + async fn record_result(&mut self) -> NestedOwn { + Host::record_result(*self).await + } + async fn func_with_handle_typedef(&mut self, x: SomeHandle) -> () { + Host::func_with_handle_typedef(*self, x).await + } + } } #[allow(clippy::all)] pub mod long_use_chain1 { @@ -589,14 +770,34 @@ pub mod foo { ) -> wasmtime::Result<()>; } #[wasmtime::component::__internal::async_trait] - pub trait Host: HostA {} - pub fn add_to_linker( + impl<_T: HostA + ?Sized + Send> HostA for &mut _T { + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostA::drop(*self, rep) + } + } + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send + HostA {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/long-use-chain1")?; inst.resource( @@ -604,13 +805,25 @@ pub mod foo { wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostA::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } #[allow(clippy::all)] pub mod long_use_chain2 { @@ -618,18 +831,41 @@ pub mod foo { use wasmtime::component::__internal::anyhow; pub type A = super::super::super::foo::foo::long_use_chain1::A; #[wasmtime::component::__internal::async_trait] - pub trait Host {} - pub fn add_to_linker( + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/long-use-chain2")?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } #[allow(clippy::all)] pub mod long_use_chain3 { @@ -637,18 +873,41 @@ pub mod foo { use wasmtime::component::__internal::anyhow; pub type A = super::super::super::foo::foo::long_use_chain2::A; #[wasmtime::component::__internal::async_trait] - pub trait Host {} - pub fn add_to_linker( + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/long-use-chain3")?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } #[allow(clippy::all)] pub mod long_use_chain4 { @@ -656,28 +915,55 @@ pub mod foo { use wasmtime::component::__internal::anyhow; pub type A = super::super::super::foo::foo::long_use_chain3::A; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn foo(&mut self) -> wasmtime::component::Resource; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/long-use-chain4")?; inst.func_wrap_async( "foo", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::foo(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn foo(&mut self) -> wasmtime::component::Resource { + Host::foo(*self).await + } + } } #[allow(clippy::all)] pub mod transitive_interface_with_resource { @@ -692,14 +978,34 @@ pub mod foo { ) -> wasmtime::Result<()>; } #[wasmtime::component::__internal::async_trait] - pub trait Host: HostFoo {} - pub fn add_to_linker( + impl<_T: HostFoo + ?Sized + Send> HostFoo for &mut _T { + fn drop( + &mut self, + rep: wasmtime::component::Resource, + ) -> wasmtime::Result<()> { + HostFoo::drop(*self, rep) + } + } + #[wasmtime::component::__internal::async_trait] + pub trait Host: Send + HostFoo {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker .instance("foo:foo/transitive-interface-with-resource")?; @@ -708,13 +1014,25 @@ pub mod foo { wasmtime::component::ResourceType::host::(), move |mut store, rep| -> wasmtime::Result<()> { HostFoo::drop( - get(store.data_mut()), + &mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep), ) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/share-types.rs b/crates/component-macro/tests/expanded/share-types.rs index b9b20e015d3..3d4a99ae116 100644 --- a/crates/component-macro/tests/expanded/share-types.rs +++ b/crates/component-macro/tests/expanded/share-types.rs @@ -111,6 +111,25 @@ pub mod foo { ); }; pub trait Host {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { + let mut inst = linker.instance("foo:foo/http-types")?; + Ok(()) + } pub fn add_to_linker( linker: &mut wasmtime::component::Linker, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, @@ -118,9 +137,9 @@ pub mod foo { where U: Host, { - let mut inst = linker.instance("foo:foo/http-types")?; - Ok(()) + add_to_linker_get_host(linker, get) } + impl<_T: Host + ?Sized> Host for &mut _T {} } } } @@ -141,24 +160,47 @@ pub mod http_fetch { pub trait Host { fn fetch_request(&mut self, request: Request) -> Response; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("http-fetch")?; inst.func_wrap( "fetch-request", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Request,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::fetch_request(host, arg0); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn fetch_request(&mut self, request: Request) -> Response { + Host::fetch_request(*self, request) + } + } } pub mod exports { #[allow(clippy::all)] diff --git a/crates/component-macro/tests/expanded/share-types_async.rs b/crates/component-macro/tests/expanded/share-types_async.rs index 2f7e12bcbb7..763701a5e20 100644 --- a/crates/component-macro/tests/expanded/share-types_async.rs +++ b/crates/component-macro/tests/expanded/share-types_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::http_types::Host + http_fetch::Host + Send, T: Send, + U: foo::foo::http_types::Host + http_fetch::Host + Send, { foo::foo::http_types::add_to_linker(linker, get)?; http_fetch::add_to_linker(linker, get)?; @@ -112,18 +112,41 @@ pub mod foo { ); }; #[wasmtime::component::__internal::async_trait] - pub trait Host {} - pub fn add_to_linker( + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/http-types")?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } } } @@ -142,28 +165,55 @@ pub mod http_fetch { assert!(4 == < Response as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn fetch_request(&mut self, request: Request) -> Response; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("http-fetch")?; inst.func_wrap_async( "fetch-request", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (Request,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::fetch_request(host, arg0).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn fetch_request(&mut self, request: Request) -> Response { + Host::fetch_request(*self, request).await + } + } } pub mod exports { #[allow(clippy::all)] diff --git a/crates/component-macro/tests/expanded/simple-functions.rs b/crates/component-macro/tests/expanded/simple-functions.rs index 2c70a61c645..5b9ede05cc5 100644 --- a/crates/component-macro/tests/expanded/simple-functions.rs +++ b/crates/component-macro/tests/expanded/simple-functions.rs @@ -79,18 +79,27 @@ pub mod foo { fn f5(&mut self) -> (u32, u32); fn f6(&mut self, a: u32, b: u32, c: u32) -> (u32, u32, u32); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/simple")?; inst.func_wrap( "f1", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f1(host); Ok(r) }, @@ -98,7 +107,7 @@ pub mod foo { inst.func_wrap( "f2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u32,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f2(host, arg0); Ok(r) }, @@ -109,7 +118,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0, arg1): (u32, u32)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f3(host, arg0, arg1); Ok(r) }, @@ -117,7 +126,7 @@ pub mod foo { inst.func_wrap( "f4", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f4(host); Ok((r,)) }, @@ -125,7 +134,7 @@ pub mod foo { inst.func_wrap( "f5", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f5(host); Ok((r,)) }, @@ -136,13 +145,42 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0, arg1, arg2): (u32, u32, u32)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f6(host, arg0, arg1, arg2); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn f1(&mut self) -> () { + Host::f1(*self) + } + fn f2(&mut self, a: u32) -> () { + Host::f2(*self, a) + } + fn f3(&mut self, a: u32, b: u32) -> () { + Host::f3(*self, a, b) + } + fn f4(&mut self) -> u32 { + Host::f4(*self) + } + fn f5(&mut self) -> (u32, u32) { + Host::f5(*self) + } + fn f6(&mut self, a: u32, b: u32, c: u32) -> (u32, u32, u32) { + Host::f6(*self, a, b, c) + } + } } } } diff --git a/crates/component-macro/tests/expanded/simple-functions_async.rs b/crates/component-macro/tests/expanded/simple-functions_async.rs index 9ee97d98eb0..9eb7fb16f66 100644 --- a/crates/component-macro/tests/expanded/simple-functions_async.rs +++ b/crates/component-macro/tests/expanded/simple-functions_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::simple::Host + Send, T: Send, + U: foo::foo::simple::Host + Send, { foo::foo::simple::add_to_linker(linker, get)?; Ok(()) @@ -73,7 +73,7 @@ pub mod foo { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn f1(&mut self) -> (); async fn f2(&mut self, a: u32) -> (); async fn f3(&mut self, a: u32, b: u32) -> (); @@ -81,19 +81,30 @@ pub mod foo { async fn f5(&mut self) -> (u32, u32); async fn f6(&mut self, a: u32, b: u32, c: u32) -> (u32, u32, u32); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/simple")?; inst.func_wrap_async( "f1", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f1(host).await; Ok(r) }), @@ -101,7 +112,7 @@ pub mod foo { inst.func_wrap_async( "f2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (u32,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f2(host, arg0).await; Ok(r) }), @@ -112,7 +123,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0, arg1): (u32, u32)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f3(host, arg0, arg1).await; Ok(r) }), @@ -120,7 +131,7 @@ pub mod foo { inst.func_wrap_async( "f4", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f4(host).await; Ok((r,)) }), @@ -128,7 +139,7 @@ pub mod foo { inst.func_wrap_async( "f5", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f5(host).await; Ok((r,)) }), @@ -139,13 +150,44 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0, arg1, arg2): (u32, u32, u32)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::f6(host, arg0, arg1, arg2).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn f1(&mut self) -> () { + Host::f1(*self).await + } + async fn f2(&mut self, a: u32) -> () { + Host::f2(*self, a).await + } + async fn f3(&mut self, a: u32, b: u32) -> () { + Host::f3(*self, a, b).await + } + async fn f4(&mut self) -> u32 { + Host::f4(*self).await + } + async fn f5(&mut self) -> (u32, u32) { + Host::f5(*self).await + } + async fn f6(&mut self, a: u32, b: u32, c: u32) -> (u32, u32, u32) { + Host::f6(*self, a, b, c).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/simple-lists.rs b/crates/component-macro/tests/expanded/simple-lists.rs index 0a6722245d3..36a6f06bc76 100644 --- a/crates/component-macro/tests/expanded/simple-lists.rs +++ b/crates/component-macro/tests/expanded/simple-lists.rs @@ -96,13 +96,22 @@ pub mod foo { wasmtime::component::__internal::Vec, >; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/simple-lists")?; inst.func_wrap( "simple-list1", @@ -110,7 +119,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::simple_list1(host, arg0); Ok(r) }, @@ -118,7 +127,7 @@ pub mod foo { inst.func_wrap( "simple-list2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::simple_list2(host); Ok((r,)) }, @@ -135,7 +144,7 @@ pub mod foo { wasmtime::component::__internal::Vec, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::simple_list3(host, arg0, arg1); Ok((r,)) }, @@ -152,13 +161,53 @@ pub mod foo { >, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::simple_list4(host, arg0); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn simple_list1( + &mut self, + l: wasmtime::component::__internal::Vec, + ) -> () { + Host::simple_list1(*self, l) + } + fn simple_list2(&mut self) -> wasmtime::component::__internal::Vec { + Host::simple_list2(*self) + } + fn simple_list3( + &mut self, + a: wasmtime::component::__internal::Vec, + b: wasmtime::component::__internal::Vec, + ) -> ( + wasmtime::component::__internal::Vec, + wasmtime::component::__internal::Vec, + ) { + Host::simple_list3(*self, a, b) + } + fn simple_list4( + &mut self, + l: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + > { + Host::simple_list4(*self, l) + } + } } } } diff --git a/crates/component-macro/tests/expanded/simple-lists_async.rs b/crates/component-macro/tests/expanded/simple-lists_async.rs index e789631cbd6..da455ce7384 100644 --- a/crates/component-macro/tests/expanded/simple-lists_async.rs +++ b/crates/component-macro/tests/expanded/simple-lists_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::simple_lists::Host + Send, T: Send, + U: foo::foo::simple_lists::Host + Send, { foo::foo::simple_lists::add_to_linker(linker, get)?; Ok(()) @@ -75,7 +75,7 @@ pub mod foo { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn simple_list1( &mut self, l: wasmtime::component::__internal::Vec, @@ -100,13 +100,24 @@ pub mod foo { wasmtime::component::__internal::Vec, >; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/simple-lists")?; inst.func_wrap_async( @@ -115,7 +126,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::Vec,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::simple_list1(host, arg0).await; Ok(r) }), @@ -123,7 +134,7 @@ pub mod foo { inst.func_wrap_async( "simple-list2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::simple_list2(host).await; Ok((r,)) }), @@ -140,7 +151,7 @@ pub mod foo { wasmtime::component::__internal::Vec, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::simple_list3(host, arg0, arg1).await; Ok((r,)) }), @@ -157,13 +168,57 @@ pub mod foo { >, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::simple_list4(host, arg0).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn simple_list1( + &mut self, + l: wasmtime::component::__internal::Vec, + ) -> () { + Host::simple_list1(*self, l).await + } + async fn simple_list2( + &mut self, + ) -> wasmtime::component::__internal::Vec { + Host::simple_list2(*self).await + } + async fn simple_list3( + &mut self, + a: wasmtime::component::__internal::Vec, + b: wasmtime::component::__internal::Vec, + ) -> ( + wasmtime::component::__internal::Vec, + wasmtime::component::__internal::Vec, + ) { + Host::simple_list3(*self, a, b).await + } + async fn simple_list4( + &mut self, + l: wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + >, + ) -> wasmtime::component::__internal::Vec< + wasmtime::component::__internal::Vec, + > { + Host::simple_list4(*self, l).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/simple-wasi.rs b/crates/component-macro/tests/expanded/simple-wasi.rs index acbb1b27ca7..5efd628b4a5 100644 --- a/crates/component-macro/tests/expanded/simple-wasi.rs +++ b/crates/component-macro/tests/expanded/simple-wasi.rs @@ -124,18 +124,27 @@ pub mod foo { fn create_directory_at(&mut self) -> Result<(), Errno>; fn stat(&mut self) -> Result; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/wasi-filesystem")?; inst.func_wrap( "create-directory-at", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::create_directory_at(host); Ok((r,)) }, @@ -143,19 +152,55 @@ pub mod foo { inst.func_wrap( "stat", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::stat(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn create_directory_at(&mut self) -> Result<(), Errno> { + Host::create_directory_at(*self) + } + fn stat(&mut self) -> Result { + Host::stat(*self) + } + } } #[allow(clippy::all)] pub mod wall_clock { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; pub trait Host {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { + let mut inst = linker.instance("foo:foo/wall-clock")?; + Ok(()) + } pub fn add_to_linker( linker: &mut wasmtime::component::Linker, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, @@ -163,9 +208,9 @@ pub mod foo { where U: Host, { - let mut inst = linker.instance("foo:foo/wall-clock")?; - Ok(()) + add_to_linker_get_host(linker, get) } + impl<_T: Host + ?Sized> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/simple-wasi_async.rs b/crates/component-macro/tests/expanded/simple-wasi_async.rs index f05bda417b8..3fdd72a0869 100644 --- a/crates/component-macro/tests/expanded/simple-wasi_async.rs +++ b/crates/component-macro/tests/expanded/simple-wasi_async.rs @@ -8,8 +8,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::wasi_filesystem::Host + foo::foo::wall_clock::Host + Send, T: Send, + U: foo::foo::wasi_filesystem::Host + foo::foo::wall_clock::Host + Send, { foo::foo::wasi_filesystem::add_to_linker(linker, get)?; foo::foo::wall_clock::add_to_linker(linker, get)?; @@ -122,23 +122,34 @@ pub mod foo { assert!(1 == < Errno as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn create_directory_at(&mut self) -> Result<(), Errno>; async fn stat(&mut self) -> Result; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/wasi-filesystem")?; inst.func_wrap_async( "create-directory-at", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::create_directory_at(host).await; Ok((r,)) }), @@ -146,31 +157,73 @@ pub mod foo { inst.func_wrap_async( "stat", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::stat(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn create_directory_at(&mut self) -> Result<(), Errno> { + Host::create_directory_at(*self).await + } + async fn stat(&mut self) -> Result { + Host::stat(*self).await + } + } } #[allow(clippy::all)] pub mod wall_clock { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host {} - pub fn add_to_linker( + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/wall-clock")?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/small-anonymous.rs b/crates/component-macro/tests/expanded/small-anonymous.rs index c87be98d5b0..beb51a5719d 100644 --- a/crates/component-macro/tests/expanded/small-anonymous.rs +++ b/crates/component-macro/tests/expanded/small-anonymous.rs @@ -120,24 +120,49 @@ pub mod foo { &mut self, ) -> Result, Error>; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/anon")?; inst.func_wrap( "option-test", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_test(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn option_test( + &mut self, + ) -> Result, Error> { + Host::option_test(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/small-anonymous_async.rs b/crates/component-macro/tests/expanded/small-anonymous_async.rs index fcc4e11592b..16876dd89b6 100644 --- a/crates/component-macro/tests/expanded/small-anonymous_async.rs +++ b/crates/component-macro/tests/expanded/small-anonymous_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::anon::Host + Send, T: Send, + U: foo::foo::anon::Host + Send, { foo::foo::anon::add_to_linker(linker, get)?; Ok(()) @@ -117,30 +117,59 @@ pub mod foo { assert!(1 == < Error as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn option_test( &mut self, ) -> Result, Error>; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/anon")?; inst.func_wrap_async( "option-test", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_test(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn option_test( + &mut self, + ) -> Result, Error> { + Host::option_test(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/smoke.rs b/crates/component-macro/tests/expanded/smoke.rs index e2bf1e2426b..7ab446dfefe 100644 --- a/crates/component-macro/tests/expanded/smoke.rs +++ b/crates/component-macro/tests/expanded/smoke.rs @@ -60,22 +60,45 @@ pub mod imports { pub trait Host { fn y(&mut self) -> (); } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("imports")?; inst.func_wrap( "y", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::y(host); Ok(r) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn y(&mut self) -> () { + Host::y(*self) + } + } } diff --git a/crates/component-macro/tests/expanded/smoke_async.rs b/crates/component-macro/tests/expanded/smoke_async.rs index 7f4c67909fa..a84a78826ac 100644 --- a/crates/component-macro/tests/expanded/smoke_async.rs +++ b/crates/component-macro/tests/expanded/smoke_async.rs @@ -8,8 +8,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: imports::Host + Send, T: Send, + U: imports::Host + Send, { imports::add_to_linker(linker, get)?; Ok(()) @@ -59,26 +59,53 @@ pub mod imports { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn y(&mut self) -> (); } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("imports")?; inst.func_wrap_async( "y", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::y(host).await; Ok(r) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn y(&mut self) -> () { + Host::y(*self).await + } + } } diff --git a/crates/component-macro/tests/expanded/strings.rs b/crates/component-macro/tests/expanded/strings.rs index 282abdb1748..1f9630e7ef2 100644 --- a/crates/component-macro/tests/expanded/strings.rs +++ b/crates/component-macro/tests/expanded/strings.rs @@ -82,13 +82,22 @@ pub mod foo { b: wasmtime::component::__internal::String, ) -> wasmtime::component::__internal::String; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/strings")?; inst.func_wrap( "a", @@ -96,7 +105,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::String,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a(host, arg0); Ok(r) }, @@ -104,7 +113,7 @@ pub mod foo { inst.func_wrap( "b", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::b(host); Ok((r,)) }, @@ -121,13 +130,37 @@ pub mod foo { wasmtime::component::__internal::String, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::c(host, arg0, arg1); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn a(&mut self, x: wasmtime::component::__internal::String) -> () { + Host::a(*self, x) + } + fn b(&mut self) -> wasmtime::component::__internal::String { + Host::b(*self) + } + fn c( + &mut self, + a: wasmtime::component::__internal::String, + b: wasmtime::component::__internal::String, + ) -> wasmtime::component::__internal::String { + Host::c(*self, a, b) + } + } } } } diff --git a/crates/component-macro/tests/expanded/strings_async.rs b/crates/component-macro/tests/expanded/strings_async.rs index 01439090bc4..1f98471bf8f 100644 --- a/crates/component-macro/tests/expanded/strings_async.rs +++ b/crates/component-macro/tests/expanded/strings_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::strings::Host + Send, T: Send, + U: foo::foo::strings::Host + Send, { foo::foo::strings::add_to_linker(linker, get)?; Ok(()) @@ -75,7 +75,7 @@ pub mod foo { #[allow(unused_imports)] use wasmtime::component::__internal::anyhow; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn a(&mut self, x: wasmtime::component::__internal::String) -> (); async fn b(&mut self) -> wasmtime::component::__internal::String; async fn c( @@ -84,13 +84,24 @@ pub mod foo { b: wasmtime::component::__internal::String, ) -> wasmtime::component::__internal::String; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/strings")?; inst.func_wrap_async( @@ -99,7 +110,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (wasmtime::component::__internal::String,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a(host, arg0).await; Ok(r) }), @@ -107,7 +118,7 @@ pub mod foo { inst.func_wrap_async( "b", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::b(host).await; Ok((r,)) }), @@ -124,13 +135,39 @@ pub mod foo { wasmtime::component::__internal::String, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::c(host, arg0, arg1).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a(&mut self, x: wasmtime::component::__internal::String) -> () { + Host::a(*self, x).await + } + async fn b(&mut self) -> wasmtime::component::__internal::String { + Host::b(*self).await + } + async fn c( + &mut self, + a: wasmtime::component::__internal::String, + b: wasmtime::component::__internal::String, + ) -> wasmtime::component::__internal::String { + Host::c(*self, a, b).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/unversioned-foo.rs b/crates/component-macro/tests/expanded/unversioned-foo.rs index 0f21b3159b6..8e65727b505 100644 --- a/crates/component-macro/tests/expanded/unversioned-foo.rs +++ b/crates/component-macro/tests/expanded/unversioned-foo.rs @@ -90,24 +90,47 @@ pub mod foo { pub trait Host { fn g(&mut self) -> Result<(), Error>; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/a")?; inst.func_wrap( "g", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::g(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn g(&mut self) -> Result<(), Error> { + Host::g(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/unversioned-foo_async.rs b/crates/component-macro/tests/expanded/unversioned-foo_async.rs index 86b510d5f66..df7187f0ca8 100644 --- a/crates/component-macro/tests/expanded/unversioned-foo_async.rs +++ b/crates/component-macro/tests/expanded/unversioned-foo_async.rs @@ -8,8 +8,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::a::Host + Send, T: Send, + U: foo::foo::a::Host + Send, { foo::foo::a::add_to_linker(linker, get)?; Ok(()) @@ -89,28 +89,55 @@ pub mod foo { assert!(4 == < Error as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn g(&mut self) -> Result<(), Error>; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/a")?; inst.func_wrap_async( "g", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::g(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn g(&mut self) -> Result<(), Error> { + Host::g(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/use-paths.rs b/crates/component-macro/tests/expanded/use-paths.rs index 132227277fe..ecfac25afa5 100644 --- a/crates/component-macro/tests/expanded/use-paths.rs +++ b/crates/component-macro/tests/expanded/use-paths.rs @@ -80,24 +80,47 @@ pub mod foo { pub trait Host { fn a(&mut self) -> Foo; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/a")?; inst.func_wrap( "a", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn a(&mut self) -> Foo { + Host::a(*self) + } + } } #[allow(clippy::all)] pub mod b { @@ -111,24 +134,47 @@ pub mod foo { pub trait Host { fn a(&mut self) -> Foo; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/b")?; inst.func_wrap( "a", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn a(&mut self) -> Foo { + Host::a(*self) + } + } } #[allow(clippy::all)] pub mod c { @@ -142,24 +188,47 @@ pub mod foo { pub trait Host { fn a(&mut self) -> Foo; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/c")?; inst.func_wrap( "a", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn a(&mut self) -> Foo { + Host::a(*self) + } + } } } } @@ -175,22 +244,45 @@ pub mod d { pub trait Host { fn b(&mut self) -> Foo; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("d")?; inst.func_wrap( "b", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::b(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn b(&mut self) -> Foo { + Host::b(*self) + } + } } diff --git a/crates/component-macro/tests/expanded/use-paths_async.rs b/crates/component-macro/tests/expanded/use-paths_async.rs index eed98976633..c0b0644a63c 100644 --- a/crates/component-macro/tests/expanded/use-paths_async.rs +++ b/crates/component-macro/tests/expanded/use-paths_async.rs @@ -8,9 +8,9 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where + T: Send, U: foo::foo::a::Host + foo::foo::b::Host + foo::foo::c::Host + d::Host + Send, - T: Send, { foo::foo::a::add_to_linker(linker, get)?; foo::foo::b::add_to_linker(linker, get)?; @@ -80,28 +80,55 @@ pub mod foo { assert!(1 == < Foo as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn a(&mut self) -> Foo; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/a")?; inst.func_wrap_async( "a", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a(&mut self) -> Foo { + Host::a(*self).await + } + } } #[allow(clippy::all)] pub mod b { @@ -113,28 +140,55 @@ pub mod foo { assert!(1 == < Foo as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn a(&mut self) -> Foo; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/b")?; inst.func_wrap_async( "a", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a(&mut self) -> Foo { + Host::a(*self).await + } + } } #[allow(clippy::all)] pub mod c { @@ -146,28 +200,55 @@ pub mod foo { assert!(1 == < Foo as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn a(&mut self) -> Foo; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/c")?; inst.func_wrap_async( "a", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::a(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn a(&mut self) -> Foo { + Host::a(*self).await + } + } } } } @@ -181,26 +262,53 @@ pub mod d { assert!(1 == < Foo as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn b(&mut self) -> Foo; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("d")?; inst.func_wrap_async( "b", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::b(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn b(&mut self) -> Foo { + Host::b(*self).await + } + } } diff --git a/crates/component-macro/tests/expanded/variants.rs b/crates/component-macro/tests/expanded/variants.rs index e0f5584c06d..4ea37c488cd 100644 --- a/crates/component-macro/tests/expanded/variants.rs +++ b/crates/component-macro/tests/expanded/variants.rs @@ -415,18 +415,27 @@ pub mod foo { fn return_named_option(&mut self) -> Option; fn return_named_result(&mut self) -> Result; } - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F where - U: Host, + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { let mut inst = linker.instance("foo:foo/variants")?; inst.func_wrap( "e1-arg", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (E1,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::e1_arg(host, arg0); Ok(r) }, @@ -434,7 +443,7 @@ pub mod foo { inst.func_wrap( "e1-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::e1_result(host); Ok((r,)) }, @@ -442,7 +451,7 @@ pub mod foo { inst.func_wrap( "v1-arg", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (V1,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::v1_arg(host, arg0); Ok(r) }, @@ -450,7 +459,7 @@ pub mod foo { inst.func_wrap( "v1-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::v1_result(host); Ok((r,)) }, @@ -461,7 +470,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (bool,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bool_arg(host, arg0); Ok(r) }, @@ -469,7 +478,7 @@ pub mod foo { inst.func_wrap( "bool-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bool_result(host); Ok((r,)) }, @@ -494,7 +503,7 @@ pub mod foo { Option>, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_arg( host, arg0, @@ -510,7 +519,7 @@ pub mod foo { inst.func_wrap( "option-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_result(host); Ok((r,)) }, @@ -528,7 +537,7 @@ pub mod foo { arg5, ): (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::casts(host, arg0, arg1, arg2, arg3, arg4, arg5); Ok((r,)) }, @@ -556,7 +565,7 @@ pub mod foo { >, )| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_arg( host, arg0, @@ -572,7 +581,7 @@ pub mod foo { inst.func_wrap( "result-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_result(host); Ok((r,)) }, @@ -580,7 +589,7 @@ pub mod foo { inst.func_wrap( "return-result-sugar", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_result_sugar(host); Ok((r,)) }, @@ -588,7 +597,7 @@ pub mod foo { inst.func_wrap( "return-result-sugar2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_result_sugar2(host); Ok((r,)) }, @@ -596,7 +605,7 @@ pub mod foo { inst.func_wrap( "return-result-sugar3", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_result_sugar3(host); Ok((r,)) }, @@ -604,7 +613,7 @@ pub mod foo { inst.func_wrap( "return-result-sugar4", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_result_sugar4(host); Ok((r,)) }, @@ -612,7 +621,7 @@ pub mod foo { inst.func_wrap( "return-option-sugar", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_option_sugar(host); Ok((r,)) }, @@ -620,7 +629,7 @@ pub mod foo { inst.func_wrap( "return-option-sugar2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_option_sugar2(host); Ok((r,)) }, @@ -628,7 +637,7 @@ pub mod foo { inst.func_wrap( "result-simple", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_simple(host); Ok((r,)) }, @@ -639,7 +648,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (IsClone,)| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::is_clone_arg(host, arg0); Ok(r) }, @@ -647,7 +656,7 @@ pub mod foo { inst.func_wrap( "is-clone-return", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::is_clone_return(host); Ok((r,)) }, @@ -655,7 +664,7 @@ pub mod foo { inst.func_wrap( "return-named-option", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_named_option(host); Ok((r,)) }, @@ -663,13 +672,138 @@ pub mod foo { inst.func_wrap( "return-named-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_named_result(host); Ok((r,)) }, )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host, + { + add_to_linker_get_host(linker, get) + } + impl<_T: Host + ?Sized> Host for &mut _T { + fn e1_arg(&mut self, x: E1) -> () { + Host::e1_arg(*self, x) + } + fn e1_result(&mut self) -> E1 { + Host::e1_result(*self) + } + fn v1_arg(&mut self, x: V1) -> () { + Host::v1_arg(*self, x) + } + fn v1_result(&mut self) -> V1 { + Host::v1_result(*self) + } + fn bool_arg(&mut self, x: bool) -> () { + Host::bool_arg(*self, x) + } + fn bool_result(&mut self) -> bool { + Host::bool_result(*self) + } + fn option_arg( + &mut self, + a: Option, + b: Option<()>, + c: Option, + d: Option, + e: Option, + g: Option>, + ) -> () { + Host::option_arg(*self, a, b, c, d, e, g) + } + fn option_result( + &mut self, + ) -> ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ) { + Host::option_result(*self) + } + fn casts( + &mut self, + a: Casts1, + b: Casts2, + c: Casts3, + d: Casts4, + e: Casts5, + f: Casts6, + ) -> (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6) { + Host::casts(*self, a, b, c, d, e, f) + } + fn result_arg( + &mut self, + a: Result<(), ()>, + b: Result<(), E1>, + c: Result, + d: Result<(), ()>, + e: Result, + f: Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ) -> () { + Host::result_arg(*self, a, b, c, d, e, f) + } + fn result_result( + &mut self, + ) -> ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ) { + Host::result_result(*self) + } + fn return_result_sugar(&mut self) -> Result { + Host::return_result_sugar(*self) + } + fn return_result_sugar2(&mut self) -> Result<(), MyErrno> { + Host::return_result_sugar2(*self) + } + fn return_result_sugar3(&mut self) -> Result { + Host::return_result_sugar3(*self) + } + fn return_result_sugar4(&mut self) -> Result<(i32, u32), MyErrno> { + Host::return_result_sugar4(*self) + } + fn return_option_sugar(&mut self) -> Option { + Host::return_option_sugar(*self) + } + fn return_option_sugar2(&mut self) -> Option { + Host::return_option_sugar2(*self) + } + fn result_simple(&mut self) -> Result { + Host::result_simple(*self) + } + fn is_clone_arg(&mut self, a: IsClone) -> () { + Host::is_clone_arg(*self, a) + } + fn is_clone_return(&mut self) -> IsClone { + Host::is_clone_return(*self) + } + fn return_named_option(&mut self) -> Option { + Host::return_named_option(*self) + } + fn return_named_result(&mut self) -> Result { + Host::return_named_result(*self) + } + } } } } diff --git a/crates/component-macro/tests/expanded/variants_async.rs b/crates/component-macro/tests/expanded/variants_async.rs index 4a15ef135de..2863bf82540 100644 --- a/crates/component-macro/tests/expanded/variants_async.rs +++ b/crates/component-macro/tests/expanded/variants_async.rs @@ -10,8 +10,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::variants::Host + Send, T: Send, + U: foo::foo::variants::Host + Send, { foo::foo::variants::add_to_linker(linker, get)?; Ok(()) @@ -345,7 +345,7 @@ pub mod foo { assert!(4 == < IsClone as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host { + pub trait Host: Send { async fn e1_arg(&mut self, x: E1) -> (); async fn e1_result(&mut self) -> E1; async fn v1_arg(&mut self, x: V1) -> (); @@ -417,19 +417,30 @@ pub mod foo { async fn return_named_option(&mut self) -> Option; async fn return_named_result(&mut self) -> Result; } - pub fn add_to_linker( + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/variants")?; inst.func_wrap_async( "e1-arg", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (E1,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::e1_arg(host, arg0).await; Ok(r) }), @@ -437,7 +448,7 @@ pub mod foo { inst.func_wrap_async( "e1-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::e1_result(host).await; Ok((r,)) }), @@ -445,7 +456,7 @@ pub mod foo { inst.func_wrap_async( "v1-arg", move |mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (V1,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::v1_arg(host, arg0).await; Ok(r) }), @@ -453,7 +464,7 @@ pub mod foo { inst.func_wrap_async( "v1-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::v1_result(host).await; Ok((r,)) }), @@ -464,7 +475,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (bool,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bool_arg(host, arg0).await; Ok(r) }), @@ -472,7 +483,7 @@ pub mod foo { inst.func_wrap_async( "bool-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::bool_result(host).await; Ok((r,)) }), @@ -497,7 +508,7 @@ pub mod foo { Option>, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_arg( host, arg0, @@ -514,7 +525,7 @@ pub mod foo { inst.func_wrap_async( "option-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::option_result(host).await; Ok((r,)) }), @@ -532,7 +543,7 @@ pub mod foo { arg5, ): (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::casts(host, arg0, arg1, arg2, arg3, arg4, arg5) .await; Ok((r,)) @@ -561,7 +572,7 @@ pub mod foo { >, )| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_arg( host, arg0, @@ -578,7 +589,7 @@ pub mod foo { inst.func_wrap_async( "result-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_result(host).await; Ok((r,)) }), @@ -586,7 +597,7 @@ pub mod foo { inst.func_wrap_async( "return-result-sugar", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_result_sugar(host).await; Ok((r,)) }), @@ -594,7 +605,7 @@ pub mod foo { inst.func_wrap_async( "return-result-sugar2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_result_sugar2(host).await; Ok((r,)) }), @@ -602,7 +613,7 @@ pub mod foo { inst.func_wrap_async( "return-result-sugar3", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_result_sugar3(host).await; Ok((r,)) }), @@ -610,7 +621,7 @@ pub mod foo { inst.func_wrap_async( "return-result-sugar4", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_result_sugar4(host).await; Ok((r,)) }), @@ -618,7 +629,7 @@ pub mod foo { inst.func_wrap_async( "return-option-sugar", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_option_sugar(host).await; Ok((r,)) }), @@ -626,7 +637,7 @@ pub mod foo { inst.func_wrap_async( "return-option-sugar2", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_option_sugar2(host).await; Ok((r,)) }), @@ -634,7 +645,7 @@ pub mod foo { inst.func_wrap_async( "result-simple", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::result_simple(host).await; Ok((r,)) }), @@ -645,7 +656,7 @@ pub mod foo { mut caller: wasmtime::StoreContextMut<'_, T>, (arg0,): (IsClone,)| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::is_clone_arg(host, arg0).await; Ok(r) }), @@ -653,7 +664,7 @@ pub mod foo { inst.func_wrap_async( "is-clone-return", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::is_clone_return(host).await; Ok((r,)) }), @@ -661,7 +672,7 @@ pub mod foo { inst.func_wrap_async( "return-named-option", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_named_option(host).await; Ok((r,)) }), @@ -669,13 +680,140 @@ pub mod foo { inst.func_wrap_async( "return-named-result", move |mut caller: wasmtime::StoreContextMut<'_, T>, (): ()| wasmtime::component::__internal::Box::new(async move { - let host = get(caller.data_mut()); + let host = &mut host_getter(caller.data_mut()); let r = Host::return_named_result(host).await; Ok((r,)) }), )?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T { + async fn e1_arg(&mut self, x: E1) -> () { + Host::e1_arg(*self, x).await + } + async fn e1_result(&mut self) -> E1 { + Host::e1_result(*self).await + } + async fn v1_arg(&mut self, x: V1) -> () { + Host::v1_arg(*self, x).await + } + async fn v1_result(&mut self) -> V1 { + Host::v1_result(*self).await + } + async fn bool_arg(&mut self, x: bool) -> () { + Host::bool_arg(*self, x).await + } + async fn bool_result(&mut self) -> bool { + Host::bool_result(*self).await + } + async fn option_arg( + &mut self, + a: Option, + b: Option<()>, + c: Option, + d: Option, + e: Option, + g: Option>, + ) -> () { + Host::option_arg(*self, a, b, c, d, e, g).await + } + async fn option_result( + &mut self, + ) -> ( + Option, + Option<()>, + Option, + Option, + Option, + Option>, + ) { + Host::option_result(*self).await + } + async fn casts( + &mut self, + a: Casts1, + b: Casts2, + c: Casts3, + d: Casts4, + e: Casts5, + f: Casts6, + ) -> (Casts1, Casts2, Casts3, Casts4, Casts5, Casts6) { + Host::casts(*self, a, b, c, d, e, f).await + } + async fn result_arg( + &mut self, + a: Result<(), ()>, + b: Result<(), E1>, + c: Result, + d: Result<(), ()>, + e: Result, + f: Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ) -> () { + Host::result_arg(*self, a, b, c, d, e, f).await + } + async fn result_result( + &mut self, + ) -> ( + Result<(), ()>, + Result<(), E1>, + Result, + Result<(), ()>, + Result, + Result< + wasmtime::component::__internal::String, + wasmtime::component::__internal::Vec, + >, + ) { + Host::result_result(*self).await + } + async fn return_result_sugar(&mut self) -> Result { + Host::return_result_sugar(*self).await + } + async fn return_result_sugar2(&mut self) -> Result<(), MyErrno> { + Host::return_result_sugar2(*self).await + } + async fn return_result_sugar3(&mut self) -> Result { + Host::return_result_sugar3(*self).await + } + async fn return_result_sugar4(&mut self) -> Result<(i32, u32), MyErrno> { + Host::return_result_sugar4(*self).await + } + async fn return_option_sugar(&mut self) -> Option { + Host::return_option_sugar(*self).await + } + async fn return_option_sugar2(&mut self) -> Option { + Host::return_option_sugar2(*self).await + } + async fn result_simple(&mut self) -> Result { + Host::result_simple(*self).await + } + async fn is_clone_arg(&mut self, a: IsClone) -> () { + Host::is_clone_arg(*self, a).await + } + async fn is_clone_return(&mut self) -> IsClone { + Host::is_clone_return(*self).await + } + async fn return_named_option(&mut self) -> Option { + Host::return_named_option(*self).await + } + async fn return_named_result(&mut self) -> Result { + Host::return_named_result(*self).await + } + } } } } diff --git a/crates/component-macro/tests/expanded/worlds-with-types.rs b/crates/component-macro/tests/expanded/worlds-with-types.rs index 3a900a5c447..420659266dd 100644 --- a/crates/component-macro/tests/expanded/worlds-with-types.rs +++ b/crates/component-macro/tests/expanded/worlds-with-types.rs @@ -104,6 +104,25 @@ pub mod foo { assert!(2 == < T as wasmtime::component::ComponentType >::ALIGN32); }; pub trait Host {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host, + { + type Host = O; + } + pub fn add_to_linker_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> GetHost<&'a mut T>, + ) -> wasmtime::Result<()> { + let mut inst = linker.instance("foo:foo/i")?; + Ok(()) + } pub fn add_to_linker( linker: &mut wasmtime::component::Linker, get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, @@ -111,9 +130,9 @@ pub mod foo { where U: Host, { - let mut inst = linker.instance("foo:foo/i")?; - Ok(()) + add_to_linker_get_host(linker, get) } + impl<_T: Host + ?Sized> Host for &mut _T {} } } } diff --git a/crates/component-macro/tests/expanded/worlds-with-types_async.rs b/crates/component-macro/tests/expanded/worlds-with-types_async.rs index 6a3245bbcdb..f93c15a1061 100644 --- a/crates/component-macro/tests/expanded/worlds-with-types_async.rs +++ b/crates/component-macro/tests/expanded/worlds-with-types_async.rs @@ -35,8 +35,8 @@ const _: () = { get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, ) -> wasmtime::Result<()> where - U: foo::foo::i::Host + Send, T: Send, + U: foo::foo::i::Host + Send, { foo::foo::i::add_to_linker(linker, get)?; Ok(()) @@ -108,18 +108,41 @@ pub mod foo { assert!(2 == < T as wasmtime::component::ComponentType >::ALIGN32); }; #[wasmtime::component::__internal::async_trait] - pub trait Host {} - pub fn add_to_linker( + pub trait Host: Send {} + pub trait GetHost< + T, + >: Fn(T) -> >::Host + Send + Sync + Copy + 'static { + type Host: Host + Send; + } + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: Host + Send, + { + type Host = O; + } + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> where T: Send, - U: Host + Send, { let mut inst = linker.instance("foo:foo/i")?; Ok(()) } + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: Host + Send, + T: Send, + { + add_to_linker_get_host(linker, get) + } + #[wasmtime::component::__internal::async_trait] + impl<_T: Host + ?Sized + Send> Host for &mut _T {} } } } diff --git a/crates/wasi-http/src/lib.rs b/crates/wasi-http/src/lib.rs index cbccaa8836a..2d29d286fe6 100644 --- a/crates/wasi-http/src/lib.rs +++ b/crates/wasi-http/src/lib.rs @@ -27,7 +27,7 @@ //! 2. Add WASI HTTP interfaces to a [`wasmtime::component::Linker`]. This is either //! done through functions like [`proxy::add_to_linker`] (which bundles all interfaces //! in the `wasi:http/proxy` world together) or through individual interfaces like the -//! [`bindings::http::outgoing_handler::add_to_linker`] function. +//! [`bindings::http::outgoing_handler::add_to_linker_get_host`] function. //! 3. Use the previous [`wasmtime::component::Linker::instantiate`] to instantiate //! a [`wasmtime::component::Component`] within a [`wasmtime::Store`]. If you're //! targeting the `wasi:http/proxy` world, you can instantiate the component with @@ -78,6 +78,7 @@ pub mod bindings { trappable_error_type: { "wasi:http/types/error-code" => crate::HttpError, }, + skip_mut_forwarding_impls: true, }); pub use wasi::http; diff --git a/crates/wasi-http/src/proxy.rs b/crates/wasi-http/src/proxy.rs index e904f3e4dba..e3889d544b1 100644 --- a/crates/wasi-http/src/proxy.rs +++ b/crates/wasi-http/src/proxy.rs @@ -83,26 +83,37 @@ pub fn add_to_linker(l: &mut wasmtime::component::Linker) -> anyhow::Resul where T: WasiHttpView + wasmtime_wasi::WasiView, { - wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::io::poll::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::io::error::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::io::streams::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::cli::stdin::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::cli::stdout::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::cli::stderr::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::random::random::add_to_linker(l, |t| t)?; + let closure = type_annotate::(|t| t); + wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::io::poll::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::io::streams::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?; add_only_http_to_linker(l) } +// NB: workaround some rustc inference - a future refactoring may make this +// obsolete. +fn type_annotate(val: F) -> F +where + F: Fn(&mut T) -> &mut T, +{ + val +} + #[doc(hidden)] pub fn add_only_http_to_linker(l: &mut wasmtime::component::Linker) -> anyhow::Result<()> where T: WasiHttpView + wasmtime_wasi::WasiView + crate::bindings::http::types::Host, { - crate::bindings::http::outgoing_handler::add_to_linker(l, |t| t)?; - crate::bindings::http::types::add_to_linker(l, |t| t)?; + let closure = type_annotate::(|t| t); + crate::bindings::http::outgoing_handler::add_to_linker_get_host(l, closure)?; + crate::bindings::http::types::add_to_linker_get_host(l, closure)?; Ok(()) } @@ -185,15 +196,17 @@ pub mod sync { where T: WasiHttpView + wasmtime_wasi::WasiView, { - wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::sync::io::poll::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::sync::io::streams::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::io::error::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::cli::stdin::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::cli::stdout::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::cli::stderr::add_to_linker(l, |t| t)?; - wasmtime_wasi::bindings::random::random::add_to_linker(l, |t| t)?; + let closure = super::type_annotate::(|t| t); + + wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::sync::io::poll::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::sync::io::streams::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; + wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?; add_only_http_to_linker(l)?; @@ -206,8 +219,10 @@ pub mod sync { where T: WasiHttpView + wasmtime_wasi::WasiView + crate::bindings::http::types::Host, { - crate::bindings::http::outgoing_handler::add_to_linker(l, |t| t)?; - crate::bindings::http::types::add_to_linker(l, |t| t)?; + let closure = super::type_annotate::(|t| t); + + crate::bindings::http::outgoing_handler::add_to_linker_get_host(l, closure)?; + crate::bindings::http::types::add_to_linker_get_host(l, closure)?; Ok(()) } diff --git a/crates/wasi-http/src/types.rs b/crates/wasi-http/src/types.rs index 28ab768630a..acc401d3083 100644 --- a/crates/wasi-http/src/types.rs +++ b/crates/wasi-http/src/types.rs @@ -30,7 +30,7 @@ impl WasiHttpCtx { } /// A trait which provides internal WASI HTTP state. -pub trait WasiHttpView: Send { +pub trait WasiHttpView { /// Returns a mutable reference to the WASI HTTP context. fn ctx(&mut self) -> &mut WasiHttpCtx; @@ -71,10 +71,7 @@ pub trait WasiHttpView: Send { &mut self, request: hyper::Request, config: OutgoingRequestConfig, - ) -> crate::HttpResult - where - Self: Sized, - { + ) -> crate::HttpResult { Ok(default_send_request(request, config)) } @@ -84,6 +81,37 @@ pub trait WasiHttpView: Send { } } +impl WasiHttpView for &mut T { + fn ctx(&mut self) -> &mut WasiHttpCtx { + T::ctx(self) + } + + fn table(&mut self) -> &mut ResourceTable { + T::table(self) + } + + fn new_response_outparam( + &mut self, + result: tokio::sync::oneshot::Sender< + Result, types::ErrorCode>, + >, + ) -> wasmtime::Result> { + T::new_response_outparam(self, result) + } + + fn send_request( + &mut self, + request: hyper::Request, + config: OutgoingRequestConfig, + ) -> crate::HttpResult { + T::send_request(self, request, config) + } + + fn is_forbidden_header(&mut self, name: &HeaderName) -> bool { + T::is_forbidden_header(self, name) + } +} + /// Returns `true` when the header is forbidden according to this [`WasiHttpView`] implementation. pub(crate) fn is_forbidden_header(view: &mut dyn WasiHttpView, name: &HeaderName) -> bool { static FORBIDDEN_HEADERS: [HeaderName; 10] = [ diff --git a/crates/wasi-nn/Cargo.toml b/crates/wasi-nn/Cargo.toml index d12f3af2a3f..1b8dc95d99d 100644 --- a/crates/wasi-nn/Cargo.toml +++ b/crates/wasi-nn/Cargo.toml @@ -16,7 +16,7 @@ workspace = true [dependencies] # These dependencies are necessary for the WITX-generation macros to work: -anyhow = { workspace = true } +anyhow = { workspace = true, features = ['std'] } wiggle = { workspace = true, features = ["wasmtime"] } # This dependency is necessary for the WIT-generation macros to work: diff --git a/crates/wasi/src/bindings.rs b/crates/wasi/src/bindings.rs index 737301403a9..8bc4add33ab 100644 --- a/crates/wasi/src/bindings.rs +++ b/crates/wasi/src/bindings.rs @@ -33,7 +33,8 @@ pub mod sync { "wasi:io/poll/pollable": super::super::io::poll::Pollable, "wasi:io/streams/input-stream": super::super::io::streams::InputStream, "wasi:io/streams/output-stream": super::super::io::streams::OutputStream, - } + }, + skip_mut_forwarding_impls: true, }); } pub use self::generated::exports; @@ -49,10 +50,6 @@ pub mod sync { /// component through the [`Command::wasi_cli_run`] method plus /// [`Guest::call_run`](exports::wasi::cli::run::Guest::call_run). /// - /// > **Note**: it's recommended to use - /// > [`wasmtime_wasi::add_to_linker_sync`] instead of the auto-generated - /// > [`Command::add_to_linker`] here. - /// /// [async]: wasmtime::Config::async_support /// [`wasmtime_wasi::add_to_linker_sync`]: crate::add_to_linker_sync /// @@ -202,6 +199,7 @@ mod async_io { "wasi:cli/terminal-input/terminal-input": crate::stdio::TerminalInput, "wasi:cli/terminal-output/terminal-output": crate::stdio::TerminalOutput, }, + skip_mut_forwarding_impls: true, }); } @@ -218,9 +216,6 @@ pub use self::async_io::wasi::*; /// through the [`Command::wasi_cli_run`] method plus /// [`Guest::call_run`](exports::wasi::cli::run::Guest::call_run). /// -/// > **Note**: it's recommended to use [`wasmtime_wasi::add_to_linker_async`] -/// > instead of the auto-generated [`Command::add_to_linker`] here. -/// /// [async]: wasmtime::Config::async_support /// [`wasmtime_wasi::add_to_linker_async`]: crate::add_to_linker_async /// diff --git a/crates/wasi/src/ctx.rs b/crates/wasi/src/ctx.rs index 8959bc8bbfa..62c323503f0 100644 --- a/crates/wasi/src/ctx.rs +++ b/crates/wasi/src/ctx.rs @@ -581,6 +581,15 @@ pub trait WasiView: Send { fn ctx(&mut self) -> &mut WasiCtx; } +impl WasiView for &mut T { + fn table(&mut self) -> &mut ResourceTable { + T::table(self) + } + fn ctx(&mut self) -> &mut WasiCtx { + T::ctx(self) + } +} + /// Per-[`Store`] state which holds state necessary to implement WASI from this /// crate. /// diff --git a/crates/wasi/src/lib.rs b/crates/wasi/src/lib.rs index 0bc65d724c3..575f0e0d85d 100644 --- a/crates/wasi/src/lib.rs +++ b/crates/wasi/src/lib.rs @@ -285,33 +285,44 @@ pub use wasmtime::component::{ResourceTable, ResourceTableError}; /// ``` pub fn add_to_linker_async(linker: &mut Linker) -> anyhow::Result<()> { let l = linker; - crate::bindings::clocks::wall_clock::add_to_linker(l, |t| t)?; - crate::bindings::clocks::monotonic_clock::add_to_linker(l, |t| t)?; - crate::bindings::filesystem::types::add_to_linker(l, |t| t)?; - crate::bindings::filesystem::preopens::add_to_linker(l, |t| t)?; - crate::bindings::io::error::add_to_linker(l, |t| t)?; - crate::bindings::io::poll::add_to_linker(l, |t| t)?; - crate::bindings::io::streams::add_to_linker(l, |t| t)?; - crate::bindings::random::random::add_to_linker(l, |t| t)?; - crate::bindings::random::insecure::add_to_linker(l, |t| t)?; - crate::bindings::random::insecure_seed::add_to_linker(l, |t| t)?; - crate::bindings::cli::exit::add_to_linker(l, |t| t)?; - crate::bindings::cli::environment::add_to_linker(l, |t| t)?; - crate::bindings::cli::stdin::add_to_linker(l, |t| t)?; - crate::bindings::cli::stdout::add_to_linker(l, |t| t)?; - crate::bindings::cli::stderr::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_input::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_output::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_stdin::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_stdout::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_stderr::add_to_linker(l, |t| t)?; - crate::bindings::sockets::tcp::add_to_linker(l, |t| t)?; - crate::bindings::sockets::tcp_create_socket::add_to_linker(l, |t| t)?; - crate::bindings::sockets::udp::add_to_linker(l, |t| t)?; - crate::bindings::sockets::udp_create_socket::add_to_linker(l, |t| t)?; - crate::bindings::sockets::instance_network::add_to_linker(l, |t| t)?; - crate::bindings::sockets::network::add_to_linker(l, |t| t)?; - crate::bindings::sockets::ip_name_lookup::add_to_linker(l, |t| t)?; + + // NB: workaround some rustc inference - a future refactoring may make this + // obsolete. + fn type_annotate(val: F) -> F + where + F: Fn(&mut T) -> &mut T, + { + val + } + let closure = type_annotate::(|t| t); + + crate::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?; + crate::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?; + crate::bindings::filesystem::types::add_to_linker_get_host(l, closure)?; + crate::bindings::filesystem::preopens::add_to_linker_get_host(l, closure)?; + crate::bindings::io::error::add_to_linker_get_host(l, closure)?; + crate::bindings::io::poll::add_to_linker_get_host(l, closure)?; + crate::bindings::io::streams::add_to_linker_get_host(l, closure)?; + crate::bindings::random::random::add_to_linker_get_host(l, closure)?; + crate::bindings::random::insecure::add_to_linker_get_host(l, closure)?; + crate::bindings::random::insecure_seed::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::exit::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::environment::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_input::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_output::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stdin::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stdout::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stderr::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::tcp::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::tcp_create_socket::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::udp::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::udp_create_socket::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::instance_network::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::network::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::ip_name_lookup::add_to_linker_get_host(l, closure)?; Ok(()) } @@ -373,32 +384,43 @@ pub fn add_to_linker_sync( linker: &mut wasmtime::component::Linker, ) -> anyhow::Result<()> { let l = linker; - crate::bindings::clocks::wall_clock::add_to_linker(l, |t| t)?; - crate::bindings::clocks::monotonic_clock::add_to_linker(l, |t| t)?; - crate::bindings::sync::filesystem::types::add_to_linker(l, |t| t)?; - crate::bindings::filesystem::preopens::add_to_linker(l, |t| t)?; - crate::bindings::io::error::add_to_linker(l, |t| t)?; - crate::bindings::sync::io::poll::add_to_linker(l, |t| t)?; - crate::bindings::sync::io::streams::add_to_linker(l, |t| t)?; - crate::bindings::random::random::add_to_linker(l, |t| t)?; - crate::bindings::random::insecure::add_to_linker(l, |t| t)?; - crate::bindings::random::insecure_seed::add_to_linker(l, |t| t)?; - crate::bindings::cli::exit::add_to_linker(l, |t| t)?; - crate::bindings::cli::environment::add_to_linker(l, |t| t)?; - crate::bindings::cli::stdin::add_to_linker(l, |t| t)?; - crate::bindings::cli::stdout::add_to_linker(l, |t| t)?; - crate::bindings::cli::stderr::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_input::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_output::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_stdin::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_stdout::add_to_linker(l, |t| t)?; - crate::bindings::cli::terminal_stderr::add_to_linker(l, |t| t)?; - crate::bindings::sockets::tcp::add_to_linker(l, |t| t)?; - crate::bindings::sockets::tcp_create_socket::add_to_linker(l, |t| t)?; - crate::bindings::sockets::udp::add_to_linker(l, |t| t)?; - crate::bindings::sockets::udp_create_socket::add_to_linker(l, |t| t)?; - crate::bindings::sockets::instance_network::add_to_linker(l, |t| t)?; - crate::bindings::sockets::network::add_to_linker(l, |t| t)?; - crate::bindings::sockets::ip_name_lookup::add_to_linker(l, |t| t)?; + + // NB: workaround some rustc inference - a future refactoring may make this + // obsolete. + fn type_annotate(val: F) -> F + where + F: Fn(&mut T) -> &mut T, + { + val + } + let closure = type_annotate::(|t| t); + + crate::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?; + crate::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?; + crate::bindings::sync::filesystem::types::add_to_linker_get_host(l, closure)?; + crate::bindings::filesystem::preopens::add_to_linker_get_host(l, closure)?; + crate::bindings::io::error::add_to_linker_get_host(l, closure)?; + crate::bindings::sync::io::poll::add_to_linker_get_host(l, closure)?; + crate::bindings::sync::io::streams::add_to_linker_get_host(l, closure)?; + crate::bindings::random::random::add_to_linker_get_host(l, closure)?; + crate::bindings::random::insecure::add_to_linker_get_host(l, closure)?; + crate::bindings::random::insecure_seed::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::exit::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::environment::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_input::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_output::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stdin::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stdout::add_to_linker_get_host(l, closure)?; + crate::bindings::cli::terminal_stderr::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::tcp::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::tcp_create_socket::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::udp::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::udp_create_socket::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::instance_network::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::network::add_to_linker_get_host(l, closure)?; + crate::bindings::sockets::ip_name_lookup::add_to_linker_get_host(l, closure)?; Ok(()) } diff --git a/crates/wit-bindgen/src/lib.rs b/crates/wit-bindgen/src/lib.rs index a2c0c5fbde6..82eb8f8b95b 100644 --- a/crates/wit-bindgen/src/lib.rs +++ b/crates/wit-bindgen/src/lib.rs @@ -56,8 +56,9 @@ struct Wasmtime { } struct ImportFunction { + func: Function, add_to_linker: String, - sig: String, + sig: Option, } #[derive(Default)] @@ -123,6 +124,11 @@ pub struct Opts { /// Evaluate to a string literal containing the generated code rather than the generated tokens /// themselves. Mostly useful for Wasmtime internal debugging and development. pub stringify: bool, + + /// Temporary option to skip `impl Trait for &mut T` for the + /// `wasmtime-wasi` crate while that's given a chance to update its b + /// indings. + pub skip_mut_forwarding_impls: bool, } #[derive(Debug, Clone)] @@ -329,14 +335,19 @@ impl Wasmtime { // Only generate a trait signature for free functions since // resource-related functions get their trait signatures // during `type_resource`. - if let FunctionKind::Freestanding = func.kind { + let sig = if let FunctionKind::Freestanding = func.kind { gen.generate_function_trait_sig(func); - } - let sig = mem::take(&mut gen.src).into(); + Some(mem::take(&mut gen.src).into()) + } else { + None + }; gen.generate_add_function_to_linker(TypeOwner::World(world), func, "linker"); let add_to_linker = gen.src.into(); - self.import_functions - .push(ImportFunction { sig, add_to_linker }); + self.import_functions.push(ImportFunction { + func: func.clone(), + sig, + add_to_linker, + }); } WorldItem::Interface(id) => { gen.gen.interface_last_seen_as_import.insert(*id, true); @@ -546,7 +557,7 @@ impl Wasmtime { assert!(prev.is_none()); } - fn build_struct(&mut self, resolve: &Resolve, world: WorldId) { + fn build_world_struct(&mut self, resolve: &Resolve, world: WorldId) { let camel = to_rust_upper_camel_case(&resolve.worlds[world].name); uwriteln!(self.src, "pub struct {camel} {{"); for (name, (ty, _)) in self.exports.fields.iter() { @@ -554,13 +565,7 @@ impl Wasmtime { } self.src.push_str("}\n"); - let (async_, async__, send, await_) = if self.opts.async_.maybe_async() { - ("async", "_async", ":Send", ".await") - } else { - ("", "", "", "") - }; - - self.toplevel_import_trait(resolve, world); + self.world_imports_trait(resolve, world); uwriteln!(self.src, "const _: () = {{"); uwriteln!( @@ -572,7 +577,13 @@ impl Wasmtime { ); uwriteln!(self.src, "impl {camel} {{"); - self.toplevel_add_to_linker(resolve, world); + self.world_add_to_linker(resolve, world); + + let (async_, async__, send, await_) = if self.opts.async_.maybe_async() { + ("async", "_async", ":Send", ".await") + } else { + ("", "", "", "") + }; uwriteln!( self.src, " @@ -650,7 +661,7 @@ impl Wasmtime { } if !self.opts.only_interfaces { - self.build_struct(resolve, world) + self.build_world_struct(resolve, world) } let imports = mem::take(&mut self.import_interfaces); @@ -870,12 +881,12 @@ impl Wasmtime { } impl Wasmtime { - fn has_world_trait(&self, resolve: &Resolve, world: WorldId) -> bool { + fn has_world_imports_trait(&self, resolve: &Resolve, world: WorldId) -> bool { !self.import_functions.is_empty() || get_world_resources(resolve, world).count() > 0 } - fn toplevel_import_trait(&mut self, resolve: &Resolve, world: WorldId) { - if !self.has_world_trait(resolve, world) { + fn world_imports_trait(&mut self, resolve: &Resolve, world: WorldId) { + if !self.has_world_imports_trait(resolve, world) { return; } @@ -884,114 +895,184 @@ impl Wasmtime { uwriteln!(self.src, "#[wasmtime::component::__internal::async_trait]") } uwrite!(self.src, "pub trait {world_camel}Imports"); - for (i, resource) in get_world_resources(resolve, world).enumerate() { - if i == 0 { - uwrite!(self.src, ": "); - } else { - uwrite!(self.src, " + "); - } - uwrite!(self.src, "Host{}", resource.to_upper_camel_case()); + let mut supertraits = vec![]; + if self.opts.async_.maybe_async() { + supertraits.push("Send".to_string()); + } + for resource in get_world_resources(resolve, world) { + supertraits.push(format!("Host{}", resource.to_upper_camel_case())); + } + if !supertraits.is_empty() { + uwrite!(self.src, ": {}", supertraits.join(" + ")); } uwriteln!(self.src, " {{"); for f in self.import_functions.iter() { - self.src.push_str(&f.sig); - self.src.push_str("\n"); + if let Some(sig) = &f.sig { + self.src.push_str(sig); + self.src.push_str(";\n"); + } } uwriteln!(self.src, "}}"); - } - fn toplevel_add_to_linker(&mut self, resolve: &Resolve, world: WorldId) { - let has_world_trait = self.has_world_trait(resolve, world); - if self.import_interfaces.is_empty() && !has_world_trait { - return; - } - let mut interfaces = Vec::new(); - for (_, name) in self.import_interfaces.iter() { - let path = match name { - InterfaceName::Remapped { .. } => unreachable!("imported a remapped module"), - InterfaceName::Path(path) => path, - }; - interfaces.push(path.join("::")); - } - - uwrite!( + uwriteln!( self.src, " - pub fn add_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> - where U: \ + pub trait {world_camel}ImportsGetHost: + Fn(T) -> >::Host + + Send + + Sync + + Copy + + 'static + {{ + type Host: {world_camel}Imports; + }} + + impl {world_camel}ImportsGetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: {world_camel}Imports + {{ + type Host = O; + }} " ); - let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name); - let world_trait = format!("{world_camel}Imports"); - for (i, name) in interfaces - .iter() - .map(|n| format!("{n}::Host")) - .chain(if has_world_trait { - Some(world_trait.clone()) - } else { - None - }) - .enumerate() - { - if i > 0 { - self.src.push_str(" + "); - } - self.src.push_str(&name); - } - let maybe_send = if self.opts.async_.maybe_async() { - " + Send, T: Send" + // Generate impl WorldImports for &mut WorldImports + let (async_trait, maybe_send) = if self.opts.async_.maybe_async() { + ( + "#[wasmtime::component::__internal::async_trait]\n", + "+ Send", + ) } else { - "" + ("", "") }; + if !self.opts.skip_mut_forwarding_impls { + uwriteln!( + self.src, + "{async_trait}impl<_T: {world_camel}Imports + ?Sized {maybe_send}> {world_camel}Imports for &mut _T {{" + ); + // Forward each method call to &mut T + for f in self.import_functions.iter() { + if let Some(sig) = &f.sig { + self.src.push_str(sig); + uwrite!( + self.src, + "{{ {world_camel}Imports::{}(*self,", + rust_function_name(&f.func) + ); + for (name, _) in f.func.params.iter() { + uwrite!(self.src, "{},", to_rust_ident(name)); + } + uwrite!(self.src, ")"); + if self.opts.async_.is_import_async(&f.func.name) { + uwrite!(self.src, ".await"); + } + uwriteln!(self.src, "}}"); + } + } + uwriteln!(self.src, "}}"); + } + } + + fn import_interface_paths(&self) -> Vec { + self.import_interfaces + .iter() + .map(|(_, name)| match name { + InterfaceName::Path(path) => path.join("::"), + InterfaceName::Remapped { .. } => unreachable!("imported a remapped module"), + }) + .collect() + } - self.src.push_str(maybe_send); - self.src.push_str(",\n{\n"); - for name in interfaces.iter() { - uwriteln!(self.src, "{name}::add_to_linker(linker, get)?;"); + fn world_host_traits(&self, resolve: &Resolve, world: WorldId) -> Vec { + let mut traits = self + .import_interface_paths() + .iter() + .map(|path| format!("{path}::Host")) + .collect::>(); + if self.has_world_imports_trait(resolve, world) { + let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name); + traits.push(format!("{world_camel}Imports")); } - if has_world_trait { - uwriteln!(self.src, "Self::add_root_to_linker(linker, get)?;"); + if self.opts.async_.maybe_async() { + traits.push("Send".to_string()); } - uwriteln!(self.src, "Ok(())\n}}"); - if !has_world_trait { + traits + } + + fn world_add_to_linker(&mut self, resolve: &Resolve, world: WorldId) { + let has_world_imports_trait = self.has_world_imports_trait(resolve, world); + if self.import_interfaces.is_empty() && !has_world_imports_trait { return; } - uwrite!( - self.src, - " - pub fn add_root_to_linker( - linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, - ) -> wasmtime::Result<()> - where U: {world_trait}{maybe_send} - {{ - let mut linker = linker.root(); - ", - ); - for name in get_world_resources(resolve, world) { - let camel = name.to_upper_camel_case(); - uwriteln!( + let camel = to_rust_upper_camel_case(&resolve.worlds[world].name); + let data_bounds = if self.opts.async_.maybe_async() { + "T: Send," + } else { + "" + }; + if has_world_imports_trait { + uwrite!( self.src, - "linker.resource( - \"{name}\", - wasmtime::component::ResourceType::host::<{camel}>(), - move |mut store, rep| -> wasmtime::Result<()> {{ - Host{camel}::drop(get(store.data_mut()), wasmtime::component::Resource::new_own(rep)) - }}, - )?;" - ) + " + pub fn add_to_linker_imports_get_host( + linker: &mut wasmtime::component::Linker, + host_getter: impl for<'a> {camel}ImportsGetHost<&'a mut T>, + ) -> wasmtime::Result<()> + where {data_bounds} + {{ + let mut linker = linker.root(); + " + ); + for name in get_world_resources(resolve, world) { + let camel = name.to_upper_camel_case(); + uwriteln!( + self.src, + " + linker.resource( + \"{name}\", + wasmtime::component::ResourceType::host::<{camel}>(), + move |mut store, rep| -> wasmtime::Result<()> {{ + Host{camel}::drop(&mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep)) + }}, + )?;" + ); + } + for f in self.import_functions.iter() { + self.src.push_str(&f.add_to_linker); + self.src.push_str("\n"); + } + uwriteln!(self.src, "Ok(())\n}}"); } - for f in self.import_functions.iter() { - self.src.push_str(&f.add_to_linker); - self.src.push_str("\n"); + let host_bounds = format!("U: {}", self.world_host_traits(resolve, world).join(" + ")); + + if !self.opts.skip_mut_forwarding_impls { + uwriteln!( + self.src, + " + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + {data_bounds} + {host_bounds} + {{ + " + ); + if has_world_imports_trait { + uwriteln!( + self.src, + "Self::add_to_linker_imports_get_host(linker, get)?;" + ); + } + for path in self.import_interface_paths() { + uwriteln!(self.src, "{path}::add_to_linker(linker, get)?;"); + } + uwriteln!(self.src, "Ok(())\n}}"); } - uwriteln!(self.src, "Ok(())\n}}"); } } @@ -1151,13 +1232,13 @@ impl<'a> InterfaceGenerator<'a> { } } + // Generate resource trait if self.gen.opts.async_.maybe_async() { uwriteln!(self.src, "#[wasmtime::component::__internal::async_trait]") } - uwriteln!(self.src, "pub trait Host{camel} {{"); - let functions = match resource.owner { + let mut functions = match resource.owner { TypeOwner::World(id) => self.resolve.worlds[id] .imports .values() @@ -1175,16 +1256,16 @@ impl<'a> InterfaceGenerator<'a> { } }; - for func in functions { - match func.kind { - FunctionKind::Method(resource) - | FunctionKind::Static(resource) - | FunctionKind::Constructor(resource) - if id == resource => {} - _ => continue, - } + functions.retain(|func| match func.kind { + FunctionKind::Freestanding => false, + FunctionKind::Method(resource) + | FunctionKind::Static(resource) + | FunctionKind::Constructor(resource) => id == resource, + }); + for func in &functions { self.generate_function_trait_sig(func); + self.push_str(";\n"); } uwrite!( @@ -1192,6 +1273,44 @@ impl<'a> InterfaceGenerator<'a> { "fn drop(&mut self, rep: wasmtime::component::Resource<{camel}>) -> wasmtime::Result<()>;"); uwriteln!(self.src, "}}"); + + // Generate impl HostResource for &mut HostResource + if !self.gen.opts.skip_mut_forwarding_impls { + let (async_trait, maybe_send) = if self.gen.opts.async_.maybe_async() { + ( + "#[wasmtime::component::__internal::async_trait]\n", + "+ Send", + ) + } else { + ("", "") + }; + uwriteln!( + self.src, + "{async_trait}impl <_T: Host{camel} + ?Sized {maybe_send}> Host{camel} for &mut _T {{" + ); + for func in &functions { + self.generate_function_trait_sig(func); + uwrite!( + self.src, + "{{ Host{camel}::{}(*self,", + rust_function_name(func) + ); + for (name, _) in func.params.iter() { + uwrite!(self.src, "{},", to_rust_ident(name)); + } + uwrite!(self.src, ")"); + if self.gen.opts.async_.is_import_async(&func.name) { + uwrite!(self.src, ".await"); + } + uwriteln!(self.src, "}}"); + } + uwriteln!(self.src, " + fn drop(&mut self, rep: wasmtime::component::Resource<{camel}>) -> wasmtime::Result<()> {{ + Host{camel}::drop(*self, rep) + }}", + ); + uwriteln!(self.src, "}}"); + } } else { self.rustdoc(docs); uwriteln!( @@ -1749,20 +1868,23 @@ impl<'a> InterfaceGenerator<'a> { let iface = &self.resolve.interfaces[id]; let owner = TypeOwner::Interface(id); - if self.gen.opts.async_.maybe_async() { + let is_maybe_async = self.gen.opts.async_.maybe_async(); + if is_maybe_async { uwriteln!(self.src, "#[wasmtime::component::__internal::async_trait]") } // Generate the `pub trait` which represents the host functionality for // this import which additionally inherits from all resource traits // for this interface defined by `type_resource`. uwrite!(self.src, "pub trait Host"); - for (i, resource) in get_resources(self.resolve, id).enumerate() { - if i == 0 { - uwrite!(self.src, ": "); - } else { - uwrite!(self.src, " + "); - } - uwrite!(self.src, "Host{}", resource.to_upper_camel_case()); + let mut host_supertraits = vec![]; + if is_maybe_async { + host_supertraits.push("Send".to_string()); + } + for resource in get_resources(self.resolve, id) { + host_supertraits.push(format!("Host{}", resource.to_upper_camel_case())); + } + if !host_supertraits.is_empty() { + uwrite!(self.src, ": {}", host_supertraits.join(" + ")); } uwriteln!(self.src, " {{"); for (_, func) in iface.functions.iter() { @@ -1771,12 +1893,13 @@ impl<'a> InterfaceGenerator<'a> { _ => continue, } self.generate_function_trait_sig(func); + self.push_str(";\n"); } // Generate `convert_*` functions to convert custom trappable errors // into the representation required by Wasmtime's component API. let mut required_conversion_traits = IndexSet::new(); - let mut errors_converted = IndexSet::new(); + let mut errors_converted = IndexMap::new(); let my_error_types = iface .types .iter() @@ -1787,9 +1910,10 @@ impl<'a> InterfaceGenerator<'a> { .iter() .filter_map(|(_, func)| self.special_case_trappable_error(&func.results)) .map(|(_, id, _)| id); - for err in my_error_types.chain(used_error_types).collect::>() { - let custom_name = &self.gen.trappable_errors[&err]; - let err = &self.resolve.types[resolve_type_definition_id(self.resolve, err)]; + let root = self.path_to_root(); + for err_id in my_error_types.chain(used_error_types).collect::>() { + let custom_name = &self.gen.trappable_errors[&err_id]; + let err = &self.resolve.types[resolve_type_definition_id(self.resolve, err_id)]; let err_name = err.name.as_ref().unwrap(); let err_snake = err_name.to_snake_case(); let err_camel = err_name.to_upper_camel_case(); @@ -1802,8 +1926,7 @@ impl<'a> InterfaceGenerator<'a> { required_conversion_traits.insert(format!("{path}::Host")); } None => { - if errors_converted.insert(err_name) { - let root = self.path_to_root(); + if errors_converted.insert(err_name, err_id).is_none() { uwriteln!( self.src, "fn convert_{err_snake}(&mut self, err: {root}{custom_name}) -> wasmtime::Result<{err_camel}>;" @@ -1814,25 +1937,41 @@ impl<'a> InterfaceGenerator<'a> { } uwriteln!(self.src, "}}"); - let mut where_clause = if self.gen.opts.async_.maybe_async() { - "T: Send, U: Host + Send".to_string() + let (data_bounds, mut host_bounds) = if self.gen.opts.async_.maybe_async() { + ("T: Send,", "Host + Send".to_string()) } else { - "U: Host".to_string() + ("", "Host".to_string()) }; - - for t in required_conversion_traits { - where_clause.push_str(" + "); - where_clause.push_str(&t); + for ty in required_conversion_traits { + uwrite!(host_bounds, " + {ty}"); } uwriteln!( self.src, " - pub fn add_to_linker( + pub trait GetHost: + Fn(T) -> >::Host + + Send + + Sync + + Copy + + 'static + {{ + type Host: {host_bounds}; + }} + + impl GetHost for F + where + F: Fn(T) -> O + Send + Sync + Copy + 'static, + O: {host_bounds}, + {{ + type Host = O; + }} + + pub fn add_to_linker_get_host( linker: &mut wasmtime::component::Linker, - get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + host_getter: impl for<'a> GetHost<&'a mut T>, ) -> wasmtime::Result<()> - where {where_clause} + where {data_bounds} {{ " ); @@ -1846,7 +1985,7 @@ impl<'a> InterfaceGenerator<'a> { \"{name}\", wasmtime::component::ResourceType::host::<{camel}>(), move |mut store, rep| -> wasmtime::Result<()> {{ - Host{camel}::drop(get(store.data_mut()), wasmtime::component::Resource::new_own(rep)) + Host{camel}::drop(&mut host_getter(store.data_mut()), wasmtime::component::Resource::new_own(rep)) }}, )?;" ) @@ -1857,6 +1996,68 @@ impl<'a> InterfaceGenerator<'a> { } uwriteln!(self.src, "Ok(())"); uwriteln!(self.src, "}}"); + + if !self.gen.opts.skip_mut_forwarding_impls { + // Generate add_to_linker (with closure) + uwriteln!( + self.src, + " + pub fn add_to_linker( + linker: &mut wasmtime::component::Linker, + get: impl Fn(&mut T) -> &mut U + Send + Sync + Copy + 'static, + ) -> wasmtime::Result<()> + where + U: {host_bounds}, {data_bounds} + {{ + add_to_linker_get_host(linker, get) + }} + " + ); + + // Generate impl Host for &mut Host + let (async_trait, maybe_send) = if is_maybe_async { + ( + "#[wasmtime::component::__internal::async_trait]\n", + "+ Send", + ) + } else { + ("", "") + }; + + uwriteln!( + self.src, + "{async_trait}impl<_T: Host + ?Sized {maybe_send}> Host for &mut _T {{" + ); + // Forward each method call to &mut T + for (_, func) in iface.functions.iter() { + match func.kind { + FunctionKind::Freestanding => {} + _ => continue, + } + self.generate_function_trait_sig(func); + uwrite!(self.src, "{{ Host::{}(*self,", rust_function_name(func)); + for (name, _) in func.params.iter() { + uwrite!(self.src, "{},", to_rust_ident(name)); + } + uwrite!(self.src, ")"); + if self.gen.opts.async_.is_import_async(&func.name) { + uwrite!(self.src, ".await"); + } + uwriteln!(self.src, "}}"); + } + for (err_name, err_id) in errors_converted { + uwriteln!( + self.src, + "fn convert_{err_snake}(&mut self, err: {root}{custom_name}) -> wasmtime::Result<{err_camel}> {{ + Host::convert_{err_snake}(*self, err) + }}", + custom_name = self.gen.trappable_errors[&err_id], + err_snake = err_name.to_snake_case(), + err_camel = err_name.to_upper_camel_case(), + ); + } + uwriteln!(self.src, "}}"); + } } fn generate_add_function_to_linker(&mut self, owner: TypeOwner, func: &Function, linker: &str) { @@ -1938,7 +2139,8 @@ impl<'a> InterfaceGenerator<'a> { ); } - self.src.push_str("let host = get(caller.data_mut());\n"); + self.src + .push_str("let host = &mut host_getter(caller.data_mut());\n"); let func_name = rust_function_name(func); let host_trait = match func.kind { FunctionKind::Freestanding => match owner { @@ -2057,8 +2259,6 @@ impl<'a> InterfaceGenerator<'a> { self.print_result_ty(&func.results, TypeMode::Owned); self.push_str(">"); } - - self.push_str(";\n"); } fn extract_typed_function(&mut self, func: &Function) -> (String, String) { diff --git a/tests/all/component_model/bindgen.rs b/tests/all/component_model/bindgen.rs index 0a6bc363684..71397b9a06c 100644 --- a/tests/all/component_model/bindgen.rs +++ b/tests/all/component_model/bindgen.rs @@ -325,6 +325,9 @@ mod async_config { package foo:foo; world t1 { + import foo: interface { + foo: func(); + } import x: func(); import y: func(); export z: func();