From db8d6d88b8afd767f0c52d68b91afe58978d90af Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 9 Aug 2025 12:36:18 +0800 Subject: [PATCH] don't generate extra `impl` for `Eq` assertions --- src/lib.rs | 15 +---------- src/test/basic.rs | 68 +++++++++++++++-------------------------------- src/test/bound.rs | 56 +++++++++++--------------------------- src/trait_.rs | 5 ---- src/trait_/eq.rs | 35 +++--------------------- 5 files changed, 42 insertions(+), 137 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 86097689..c6865ea8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -648,20 +648,7 @@ fn generate_impl( let body = generate_body(derive_where, trait_, item, generics); let ident = item.ident(); - let mut output = trait_.impl_item(crate_, full_item, imp, ident, ty, &where_clause, body); - - if let Some((path, body)) = trait_.additional_impl() { - output.extend(quote! { - #[automatically_derived] - impl #imp #path for #ident #ty - #where_clause - { - #body - } - }) - } - - output + trait_.impl_item(crate_, full_item, imp, ident, ty, &where_clause, body) } /// Generate implementation method body for a [`Trait`]. diff --git a/src/test/basic.rs b/src/test/basic.rs index 62569221..9196b84c 100644 --- a/src/test/basic.rs +++ b/src/test/basic.rs @@ -45,23 +45,15 @@ fn struct_() -> Result<()> { } } - const _: () = { - trait DeriveWhereAssertEq { - fn assert(&self); - } - - impl DeriveWhereAssertEq for Test { - fn assert(&self) { - struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); + #[automatically_derived] + impl ::core::cmp::Eq for Test { + fn assert_receiver_is_total_eq(&self) { + struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); - // For some reason the comparison fails without the extra space at the end. - let _: __AssertEq >; - } + // place extra space to avoid token being printed as `>>` + let _: __AssertEq >; } - }; - - #[automatically_derived] - impl ::core::cmp::Eq for Test { } + } #[automatically_derived] impl ::core::hash::Hash for Test { @@ -148,23 +140,15 @@ fn tuple() -> Result<()> { } } - const _: () = { - trait DeriveWhereAssertEq { - fn assert(&self); - } - - impl DeriveWhereAssertEq for Test { - fn assert(&self) { - struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); + #[automatically_derived] + impl ::core::cmp::Eq for Test { + fn assert_receiver_is_total_eq(&self) { + struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); - // For some reason the comparison fails without the extra space at the end. - let _: __AssertEq >; - } + // place extra space to avoid token being printed as `>>` + let _: __AssertEq >; } - }; - - #[automatically_derived] - impl ::core::cmp::Eq for Test { } + } #[automatically_derived] impl ::core::hash::Hash for Test { @@ -301,24 +285,16 @@ fn enum_() -> Result<()> { } } - const _: () = { - trait DeriveWhereAssertEq { - fn assert(&self); - } - - impl DeriveWhereAssertEq for Test { - fn assert(&self) { - struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); + #[automatically_derived] + impl ::core::cmp::Eq for Test { + fn assert_receiver_is_total_eq(&self) { + struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); - // For some reason the comparison fails without the extra space at the end. - let _: __AssertEq >; - let _: __AssertEq >; - } + // place extra space to avoid token being printed as `>>` + let _: __AssertEq >; + let _: __AssertEq >; } - }; - - #[automatically_derived] - impl ::core::cmp::Eq for Test { } + } #[automatically_derived] impl ::core::hash::Hash for Test { diff --git a/src/test/bound.rs b/src/test/bound.rs index c9bcfb49..1cfa93c0 100644 --- a/src/test/bound.rs +++ b/src/test/bound.rs @@ -235,28 +235,17 @@ fn check_trait_bounds() -> Result<()> { } } - const _: () = { - trait DeriveWhereAssertEq { - fn assert(&self); - } - - impl DeriveWhereAssertEq for Test - where T: ::core::cmp::Eq - { - fn assert(&self) { - struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); - - // For some reason the comparison fails without the extra space at the end. - let _: __AssertEq; - let _: __AssertEq >; - } - } - }; - #[automatically_derived] impl ::core::cmp::Eq for Test where T: ::core::cmp::Eq - { } + { + fn assert_receiver_is_total_eq(&self) { + struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); + + let _: __AssertEq; + let _: __AssertEq >; + } + } #[automatically_derived] impl ::core::hash::Hash for Test @@ -386,32 +375,19 @@ fn check_multiple_trait_bounds() -> Result<()> { } } - const _: () = { - trait DeriveWhereAssertEq { - fn assert(&self); - } - - impl DeriveWhereAssertEq for Test - where - T: ::core::cmp::Eq, - U: ::core::cmp::Eq - { - fn assert(&self) { - struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); - - // For some reason the comparison fails without the extra space at the end. - let _: __AssertEq; - let _: __AssertEq >; - } - } - }; - #[automatically_derived] impl ::core::cmp::Eq for Test where T: ::core::cmp::Eq, U: ::core::cmp::Eq - { } + { + fn assert_receiver_is_total_eq(&self) { + struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); + let _: __AssertEq; + // place extra space to avoid token being printed as `>>` + let _: __AssertEq >; + } + } #[automatically_derived] impl ::core::hash::Hash for Test diff --git a/src/trait_.rs b/src/trait_.rs index 5c3fe6eb..0d94ef7c 100644 --- a/src/trait_.rs +++ b/src/trait_.rs @@ -345,11 +345,6 @@ pub trait TraitImpl: Deref { /// Returns fully qualified [`Path`] for this trait. fn path(&self) -> Path; - /// Additional implementation to add for this [`Trait`]. - fn additional_impl(&self) -> Option<(Path, TokenStream)> { - None - } - /// Trait to implement. Only used by [`Eq`] and /// [`ZeroizeOnDrop`](https://docs.rs/zeroize/latest/zeroize/trait.ZeroizeOnDrop.html). #[allow(clippy::too_many_arguments)] diff --git a/src/trait_/eq.rs b/src/trait_/eq.rs index 378b947f..1878e71e 100644 --- a/src/trait_/eq.rs +++ b/src/trait_/eq.rs @@ -1,10 +1,10 @@ //! [`Eq`](trait@std::cmp::Eq) implementation. -use std::{borrow::Cow, ops::Deref}; +use std::ops::Deref; use proc_macro2::TokenStream; use quote::quote; -use syn::{DeriveInput, Ident, ImplGenerics, Path, TypeGenerics, WhereClause}; +use syn::Path; use crate::{util, Data, DeriveTrait, DeriveWhere, Item, SplitGenerics, Trait, TraitImpl}; @@ -24,35 +24,6 @@ impl TraitImpl for Eq { util::path_from_strs(&["core", "cmp", "Eq"]) } - fn additional_impl(&self) -> Option<(Path, TokenStream)> { - Some((self.path(), quote! {})) - } - - fn impl_item( - &self, - _: Option<&Path>, - _: &DeriveInput, - imp: &ImplGenerics<'_>, - ident: &Ident, - ty: &TypeGenerics<'_>, - where_clause: &Option>, - body: TokenStream, - ) -> TokenStream { - quote! { - const _: () = { - trait DeriveWhereAssertEq { - fn assert(&self); - } - - impl #imp DeriveWhereAssertEq for #ident #ty - #where_clause - { - #body - } - }; - } - } - fn build_signature( &self, _derive_where: &DeriveWhere, @@ -61,7 +32,7 @@ impl TraitImpl for Eq { body: &TokenStream, ) -> TokenStream { quote! { - fn assert(&self) { + fn assert_receiver_is_total_eq(&self) { struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); #body