diff --git a/packages/yew-macro/src/hook/mod.rs b/packages/yew-macro/src/hook/mod.rs index df83c35753d..aabf54b3762 100644 --- a/packages/yew-macro/src/hook/mod.rs +++ b/packages/yew-macro/src/hook/mod.rs @@ -146,38 +146,46 @@ pub fn hook_impl(hook: HookFn) -> syn::Result { let inner_fn_ident = Ident::new("inner_fn", Span::mixed_site()); let input_args = hook_sig.input_args(); - // there might be some overridden lifetimes in the return type. let inner_fn_rt = match &sig.output { ReturnType::Default => None, ReturnType::Type(rarrow, _) => Some(quote! { #rarrow #output_type }), }; - let inner_fn = quote! { fn #inner_fn_ident #generics (#ctx_ident: &mut ::yew::functional::HookContext, #inputs) #inner_fn_rt #where_clause #block }; + let output_is_impl_trait = matches!(hook_sig.output_type, Type::ImplTrait(_)); - let inner_type_impl = if hook_sig.needs_boxing { - let with_output = !matches!(hook_sig.output_type, Type::ImplTrait(_),); - let inner_fn_rt = with_output.then_some(&inner_fn_rt); - let output_type = with_output.then_some(&output_type); + let inner_fn = if output_is_impl_trait { + quote! {} + } else { + quote! { fn #inner_fn_ident #generics (#ctx_ident: &mut ::yew::functional::HookContext, #inputs) #inner_fn_rt #where_clause #block } + }; + let inner_type_impl = if hook_sig.needs_boxing { let hook_lifetime = &hook_sig.hook_lifetime; - let hook_lifetime_plus = quote! { #hook_lifetime + }; - let boxed_inner_ident = Ident::new("boxed_inner", Span::mixed_site()); - let boxed_fn_type = quote! { ::std::boxed::Box }; - - let as_boxed_fn = with_output.then(|| quote! { as #boxed_fn_type }); - let generic_types = generics.type_params().map(|t| &t.ident); + if output_is_impl_trait { + quote! { + let #boxed_inner_ident = ::std::boxed::Box::new( + move |#ctx_ident: &mut ::yew::functional::HookContext| #block + ); - // We need boxing implementation for `impl Trait` arguments. - quote! { - let #boxed_inner_ident = ::std::boxed::Box::new( - move |#ctx_ident: &mut ::yew::functional::HookContext| #inner_fn_rt { - #inner_fn_ident :: <#(#generic_types,)*> (#ctx_ident, #(#input_args,)*) - } - ) #as_boxed_fn; - - ::yew::functional::BoxedHook::<#hook_lifetime, #output_type>::new(#boxed_inner_ident) + ::yew::functional::BoxedHook::<#hook_lifetime,>::new(#boxed_inner_ident) + } + } else { + let hook_lifetime_plus = quote! { #hook_lifetime + }; + let boxed_fn_type = quote! { ::std::boxed::Box }; + let as_boxed_fn = quote! { as #boxed_fn_type }; + let generic_types = generics.type_params().map(|t| &t.ident); + + quote! { + let #boxed_inner_ident = ::std::boxed::Box::new( + move |#ctx_ident: &mut ::yew::functional::HookContext| #inner_fn_rt { + #inner_fn_ident :: <#(#generic_types,)*> (#ctx_ident, #(#input_args,)*) + } + ) #as_boxed_fn; + + ::yew::functional::BoxedHook::<#hook_lifetime, #output_type>::new(#boxed_inner_ident) + } } } else { let input_types = hook_sig.input_types();