From fdc36e5c06def28b33d3154f0517969d90b744d8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 22 Oct 2024 11:08:17 -0700 Subject: [PATCH 1/3] Add regression test for issue 2846 error[E0425]: cannot find value `__e` in this scope --> test_suite/tests/regression/issue2846.rs:12:19 | 12 | declare_in_macro!("with"); | ^^^^^^ not found in this scope --- test_suite/tests/regression/issue2846.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test_suite/tests/regression/issue2846.rs diff --git a/test_suite/tests/regression/issue2846.rs b/test_suite/tests/regression/issue2846.rs new file mode 100644 index 000000000..c4a91330c --- /dev/null +++ b/test_suite/tests/regression/issue2846.rs @@ -0,0 +1,23 @@ +#![allow(clippy::trivially_copy_pass_by_ref)] + +use serde_derive::Deserialize; + +macro_rules! declare_in_macro { + ($with:literal) => { + #[derive(Deserialize)] + pub struct S(#[serde(with = $with)] i32); + }; +} + +declare_in_macro!("with"); + +mod with { + use serde::Deserializer; + + pub fn deserialize<'de, D>(_: D) -> Result + where + D: Deserializer<'de>, + { + unimplemented!() + } +} From b60e4092ec83c70e8c7d39574778349b2c5d9f05 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 22 Oct 2024 11:10:40 -0700 Subject: [PATCH 2/3] Hygiene for macro-generated newtype struct deserialization with 'with' attr --- serde_derive/src/de.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index a50010ca3..518f84320 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -875,13 +875,14 @@ fn deserialize_newtype_struct( ) -> TokenStream { let delife = params.borrowed.de_lifetime(); let field_ty = field.ty; + let deserializer_var = quote!(__e); let value = match field.attrs.deserialize_with() { None => { let span = field.original.span(); let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize); quote! { - #func(__e)? + #func(#deserializer_var)? } } Some(path) => { @@ -890,7 +891,7 @@ fn deserialize_newtype_struct( // on the #[serde(with = "...")] // ^^^^^ quote_spanned! {path.span()=> - #path(__e)? + #path(#deserializer_var)? } } }; @@ -906,7 +907,7 @@ fn deserialize_newtype_struct( quote! { #[inline] - fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result + fn visit_newtype_struct<__E>(self, #deserializer_var: __E) -> _serde::__private::Result where __E: _serde::Deserializer<#delife>, { From 79925ac3947483013ba8136e43bc0449b99bd10c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 22 Oct 2024 11:10:51 -0700 Subject: [PATCH 3/3] Ignore dead_code warning in regression test warning: field `0` is never read --> test_suite/tests/regression/issue2846.rs:8:45 | 8 | pub struct S(#[serde(with = $with)] i32); | - field in this struct ^^^ ... 12 | declare_in_macro!("with"); | ------------------------- in this macro invocation | = help: consider removing this field = note: `#[warn(dead_code)]` on by default = note: this warning originates in the macro `declare_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) --- test_suite/tests/regression/issue2846.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test_suite/tests/regression/issue2846.rs b/test_suite/tests/regression/issue2846.rs index c4a91330c..c5258a5b3 100644 --- a/test_suite/tests/regression/issue2846.rs +++ b/test_suite/tests/regression/issue2846.rs @@ -5,7 +5,11 @@ use serde_derive::Deserialize; macro_rules! declare_in_macro { ($with:literal) => { #[derive(Deserialize)] - pub struct S(#[serde(with = $with)] i32); + pub struct S( + #[serde(with = $with)] + #[allow(dead_code)] + i32, + ); }; }