From 106da4905fe44bdbd9b4f327ed80e4291625e690 Mon Sep 17 00:00:00 2001 From: "Andrew V. Teylu" Date: Fri, 1 Aug 2025 09:58:22 +0100 Subject: [PATCH] Fix temporary value lifetime in serialize_struct In the 2024 edition of Rust, `serde`s macros for `serialize_with` can lead to a temporary lifetime error such as: ``` error[E0716]: temporary value dropped while borrowed --> my-binary/src/main.rs:6:10 | 6 | #[derive(MyDerive)] | ^^^^^^^- | | | | | temporary value is freed at the end of this statement | creates a temporary value which is freed while still in use | borrow later used by call | in this derive macro expansion | ::: /private/tmp/life/my-project/my-macro/src/lib.rs:6:1 | 6 | pub fn my_derive(_input: TokenStream) -> TokenStream { | ---------------------------------------------------- in this expansion of `#[derive(MyDerive)]` | = note: consider using a `let` binding to create a longer lived value ``` This is because the macro code takes a reference to struct inside of a block, which then goes out of scope when `serde` passes it to a function. To resolve this, we move the reference to outside of the block, to ensure that the lifetime extends into the function call. Signed-off-by: Andrew V. Teylu --- serde_derive/src/ser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 46be736c..02c027c3 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -1235,7 +1235,7 @@ fn wrap_serialize_with( #serialize_with(#(#self_var.values.#field_access, )* #serializer_var) }; - quote!({ + quote!(&{ #[doc(hidden)] struct __SerializeWith #wrapper_impl_generics #where_clause { values: (#(&'__a #field_tys, )*), @@ -1252,7 +1252,7 @@ fn wrap_serialize_with( } } - &__SerializeWith { + __SerializeWith { values: (#(#field_exprs, )*), phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, }