From b1d5ab600a39291141f42c8875fd56ab92a96957 Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 7 Jan 2025 14:26:39 +0200 Subject: [PATCH 1/6] Showcase --- tests/display.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/display.rs b/tests/display.rs index 66298bdd..60f2324a 100644 --- a/tests/display.rs +++ b/tests/display.rs @@ -2017,6 +2017,43 @@ mod generic { } } + mod raw { + use super::*; + + #[derive(Display)] + struct One { + r#thing: T, + } + + #[test] + fn assert() { + assert_eq!(One:: { r#thing: 8 }.to_string(), "8"); + } + + mod interpolated { + use super::*; + + #[derive(Display)] + #[display("{thing}")] + struct One { + r#thing: T, + } + + #[derive(Display)] + #[display("{a}:{b}")] + struct Two { + r#a: A, + b: B, + } + + #[test] + fn assert() { + assert_eq!(One:: { r#thing: 8 }.to_string(), "8"); + assert_eq!(Two:: { r#a: 8, b: 16 }.to_string(), "8:16"); + } + } + } + mod bound { use super::*; From 4ce644794d1d6477c0a6aa1f9820ebd50ec7fa62 Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 7 Jan 2025 15:13:58 +0200 Subject: [PATCH 2/6] Fix showcase --- impl/src/fmt/display.rs | 15 +++++++++------ impl/src/fmt/mod.rs | 19 +++++++++++-------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/impl/src/fmt/display.rs b/impl/src/fmt/display.rs index 10cf3200..21f07638 100644 --- a/impl/src/fmt/display.rs +++ b/impl/src/fmt/display.rs @@ -292,12 +292,15 @@ impl Expansion<'_> { quote! { &derive_more::core::format_args!(#fmt, #(#deref_args),*) } } else if let Some((expr, trait_ident)) = fmt.transparent_call() { - let expr = - if self.fields.fmt_args_idents().any(|field| expr == field) { - quote! { #expr } - } else { - quote! { &(#expr) } - }; + let expr = if let Some(field) = self + .fields + .fmt_args_idents() + .find(|field| expr == *field || expr == field.unraw()) + { + quote! { #field } + } else { + quote! { &(#expr) } + }; quote! { derive_more::core::fmt::#trait_ident::fmt(#expr, __derive_more_f) } } else { diff --git a/impl/src/fmt/mod.rs b/impl/src/fmt/mod.rs index e09d3d68..1c2318bf 100644 --- a/impl/src/fmt/mod.rs +++ b/impl/src/fmt/mod.rs @@ -8,20 +8,20 @@ pub(crate) mod debug; pub(crate) mod display; mod parsing; +use crate::{ + parsing::Expr, + utils::{attr, Either, Spanning}, +}; use proc_macro2::TokenStream; use quote::{format_ident, quote, ToTokens}; use syn::{ + ext::IdentExt as _, parse::{Parse, ParseStream}, punctuated::Punctuated, spanned::Spanned as _, token, }; -use crate::{ - parsing::Expr, - utils::{attr, Either, Spanning}, -}; - /// Representation of a `bound` macro attribute, expressing additional trait bounds. /// /// ```rust,ignore @@ -140,7 +140,7 @@ impl FmtAttribute { /// Checks whether this [`FmtAttribute`] can be replaced with a transparent delegation (calling /// a formatting trait directly instead of interpolation syntax). /// - /// If such transparent call is possible, the returns an [`Ident`] of the delegated trait and + /// If such transparent call is possible, then returns an [`Ident`] of the delegated trait and /// the [`Expr`] to pass into the call, otherwise [`None`]. /// /// [`Ident`]: struct@syn::Ident @@ -228,7 +228,10 @@ impl FmtAttribute { f.unnamed.iter().nth(i).map(|f| &f.ty) } (syn::Fields::Named(f), None) => f.named.iter().find_map(|f| { - f.ident.as_ref().filter(|s| **s == name).map(|_| &f.ty) + f.ident + .as_ref() + .filter(|s| s.unraw() == name) + .map(|_| &f.ty) }), _ => None, }?; @@ -291,7 +294,7 @@ impl FmtAttribute { .collect::>(); fields.fmt_args_idents().filter_map(move |field_name| { - (used_args.iter().any(|arg| field_name == arg) + (used_args.iter().any(|arg| field_name.unraw() == arg) && !self.args.iter().any(|arg| { arg.alias.as_ref().map_or(false, |(n, _)| n == &field_name) })) From 52210fca779eae3fb423d090cc42319158ace55f Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 7 Jan 2025 15:23:31 +0200 Subject: [PATCH 3/6] Extend tests --- tests/display.rs | 49 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/tests/display.rs b/tests/display.rs index 60f2324a..31cd2317 100644 --- a/tests/display.rs +++ b/tests/display.rs @@ -2021,13 +2021,19 @@ mod generic { use super::*; #[derive(Display)] - struct One { + struct StructOne { r#thing: T, } + #[derive(Display)] + enum Enum { + One { r#thing: T }, + } + #[test] fn assert() { - assert_eq!(One:: { r#thing: 8 }.to_string(), "8"); + assert_eq!(StructOne:: { r#thing: 8 }.to_string(), "8"); + assert_eq!(Enum::::One { r#thing: 8 }.to_string(), "8"); } mod interpolated { @@ -2035,21 +2041,52 @@ mod generic { #[derive(Display)] #[display("{thing}")] - struct One { + struct StructOne { r#thing: T, } + #[derive(Display)] + enum Enum1 { + #[display("{thing}")] + One { r#thing: T }, + } + + #[derive(Display)] + #[display("{thing}")] + enum Enum1Top { + One { r#thing: T }, + } + #[derive(Display)] #[display("{a}:{b}")] - struct Two { + struct StructTwo { r#a: A, b: B, } + #[derive(Display)] + enum Enum2 { + #[display("{a}:{b}")] + Two { r#a: A, b: B }, + } + + #[derive(Display)] + #[display("{a}:{b}")] + enum Enum2Shared { + Two { r#a: A, b: B }, + } + #[test] fn assert() { - assert_eq!(One:: { r#thing: 8 }.to_string(), "8"); - assert_eq!(Two:: { r#a: 8, b: 16 }.to_string(), "8:16"); + assert_eq!(StructOne:: { r#thing: 8 }.to_string(), "8"); + assert_eq!(Enum1::::One { r#thing: 8 }.to_string(), "8"); + assert_eq!(Enum1Top::::One { r#thing: 8 }.to_string(), "8"); + assert_eq!(StructTwo:: { r#a: 8, b: 16 }.to_string(), "8:16"); + assert_eq!(Enum2::::Two { r#a: 8, b: 16 }.to_string(), "8:16"); + assert_eq!( + Enum2Shared::::Two { r#a: 8, b: 16 }.to_string(), + "8:16", + ); } } } From 3dcad92923fe6f537529516dfa58b1e583055658 Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 7 Jan 2025 15:40:13 +0200 Subject: [PATCH 4/6] Fix `Debug` too --- impl/src/fmt/debug.rs | 16 ++++++---- impl/src/fmt/mod.rs | 9 +++--- tests/debug.rs | 69 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/impl/src/fmt/debug.rs b/impl/src/fmt/debug.rs index 9d4dc0d3..07b8ad5a 100644 --- a/impl/src/fmt/debug.rs +++ b/impl/src/fmt/debug.rs @@ -4,7 +4,7 @@ use proc_macro2::TokenStream; use quote::{format_ident, quote}; -use syn::{parse_quote, spanned::Spanned as _, Ident}; +use syn::{ext::IdentExt as _, parse_quote, spanned::Spanned as _}; use crate::utils::{ attr::{self, ParseMultiple as _}, @@ -78,7 +78,7 @@ pub fn expand(input: &syn::DeriveInput, _: &str) -> syn::Result { /// [`fmt::Debug`]: std::fmt::Debug fn expand_struct( attrs: ContainerAttributes, - ident: &Ident, + ident: &syn::Ident, s: &syn::DataStruct, type_params: &[&syn::Ident], attr_name: &syn::Ident, @@ -209,8 +209,8 @@ type FieldAttribute = Either; struct Expansion<'a> { attr: &'a ContainerAttributes, - /// Struct or enum [`Ident`](struct@Ident). - ident: &'a Ident, + /// Struct or enum [`Ident`](struct@syn::Ident). + ident: &'a syn::Ident, /// Struct or enum [`syn::Fields`]. fields: &'a syn::Fields, @@ -251,8 +251,12 @@ impl Expansion<'_> { fn generate_body(&self) -> syn::Result { if let Some(fmt) = &self.attr.fmt { return Ok(if let Some((expr, trait_ident)) = fmt.transparent_call() { - let expr = if self.fields.fmt_args_idents().any(|field| expr == field) { - quote! { #expr } + let expr = if let Some(field) = self + .fields + .fmt_args_idents() + .find(|field| expr == *field || expr == field.unraw()) + { + quote! { #field } } else { quote! { &(#expr) } }; diff --git a/impl/src/fmt/mod.rs b/impl/src/fmt/mod.rs index 1c2318bf..56d75e1c 100644 --- a/impl/src/fmt/mod.rs +++ b/impl/src/fmt/mod.rs @@ -8,10 +8,6 @@ pub(crate) mod debug; pub(crate) mod display; mod parsing; -use crate::{ - parsing::Expr, - utils::{attr, Either, Spanning}, -}; use proc_macro2::TokenStream; use quote::{format_ident, quote, ToTokens}; use syn::{ @@ -22,6 +18,11 @@ use syn::{ token, }; +use crate::{ + parsing::Expr, + utils::{attr, Either, Spanning}, +}; + /// Representation of a `bound` macro attribute, expressing additional trait bounds. /// /// ```rust,ignore diff --git a/tests/debug.rs b/tests/debug.rs index aa886b01..a60e79d9 100644 --- a/tests/debug.rs +++ b/tests/debug.rs @@ -1820,6 +1820,75 @@ mod generic { } } + mod raw { + use derive_more::Debug; + + #[derive(Debug)] + struct StructOne { + r#thing: T, + } + + #[derive(Debug)] + enum Enum { + One { r#thing: T }, + } + + #[test] + fn assert() { + assert_eq!( + format!("{:?}", StructOne:: { r#thing: 8 }), + "StructOne { r#thing: 8 }" + ); + assert_eq!( + format!("{:?}", Enum::::One { r#thing: 8 }), + "One { r#thing: 8 }" + ); + } + + mod interpolated { + use derive_more::Debug; + + #[derive(Debug)] + #[debug("{thing}")] + struct StructOne { + r#thing: T, + } + + #[derive(Debug)] + enum Enum1 { + #[debug("{thing}")] + One { r#thing: T }, + } + + #[derive(Debug)] + #[debug("{a}:{b}")] + struct StructTwo { + r#a: A, + b: B, + } + + #[derive(Debug)] + enum Enum2 { + #[debug("{a}:{b}")] + Two { r#a: A, b: B }, + } + + #[test] + fn assert() { + assert_eq!(format!("{:?}", StructOne:: { r#thing: 8 }), "8"); + assert_eq!(format!("{:?}", Enum1::::One { r#thing: 8 }), "8"); + assert_eq!( + format!("{:?}", StructTwo:: { r#a: 8, b: 16 }), + "8:16", + ); + assert_eq!( + format!("{:?}", Enum2::::Two { r#a: 8, b: 16 }), + "8:16", + ); + } + } + } + mod bound { #[cfg(not(feature = "std"))] use alloc::format; From 83a5830e115f3d7900fed1679b05b2134850b18c Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 7 Jan 2025 15:42:29 +0200 Subject: [PATCH 5/6] Mention in CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 576d050b..152e7144 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Top-level `#[display("...")]` attribute on an enum being incorrectly treated as transparent or wrapping. ([#395](https://github.com/JelteF/derive_more/pull/395)) +- Omitted raw identifiers in `Debug` and `Display` expansions. + ([#431](https://github.com/JelteF/derive_more/pull/431)) ## 1.0.0 - 2024-08-07 From 27dd937254de3232ddc790b006aa9a261d069fc5 Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 7 Jan 2025 15:45:20 +0200 Subject: [PATCH 6/6] Fix `Debug` tests --- tests/debug.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/debug.rs b/tests/debug.rs index a60e79d9..0f516ea8 100644 --- a/tests/debug.rs +++ b/tests/debug.rs @@ -1821,6 +1821,9 @@ mod generic { } mod raw { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)] @@ -1846,6 +1849,9 @@ mod generic { } mod interpolated { + #[cfg(not(feature = "std"))] + use alloc::format; + use derive_more::Debug; #[derive(Debug)]