diff --git a/.config/topic.dic b/.config/topic.dic index 1d556917..e6947e15 100644 --- a/.config/topic.dic +++ b/.config/topic.dic @@ -1,5 +1,6 @@ -18 +19 ≥1 +APIs Changelog CHANGELOG derive_bounded diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d4f1c8b..b115f626 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `no_drop` item-level option to `ZeroizeOnDrop` which does not implement `Drop` but instead only asserts that every field implements `ZeroizeOnDrop`. +### Fixed +- Stop depending on unstable APIs for `Eq` for `ZeroizeOnDrop`. + ## [1.4.0] - 2025-05-01 ### Added diff --git a/src/test/basic.rs b/src/test/basic.rs index c0fa45ba..62569221 100644 --- a/src/test/basic.rs +++ b/src/test/basic.rs @@ -45,16 +45,23 @@ fn struct_() -> Result<()> { } } - #[automatically_derived] - impl ::core::cmp::Eq for Test { - #[inline] - fn assert_receiver_is_total_eq(&self) { - struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); + const _: () = { + trait DeriveWhereAssertEq { + fn assert(&self); + } - // For some reason the comparison fails without the extra space at the end. - let _: __AssertEq >; + impl DeriveWhereAssertEq for Test { + 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 >; + } } - } + }; + + #[automatically_derived] + impl ::core::cmp::Eq for Test { } #[automatically_derived] impl ::core::hash::Hash for Test { @@ -141,16 +148,23 @@ fn tuple() -> Result<()> { } } - #[automatically_derived] - impl ::core::cmp::Eq for Test { - #[inline] - fn assert_receiver_is_total_eq(&self) { - struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); + 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>); - // For some reason the comparison fails without the extra space at the end. - let _: __AssertEq >; + // For some reason the comparison fails without the extra space at the end. + let _: __AssertEq >; + } } - } + }; + + #[automatically_derived] + impl ::core::cmp::Eq for Test { } #[automatically_derived] impl ::core::hash::Hash for Test { @@ -287,17 +301,24 @@ fn enum_() -> Result<()> { } } - #[automatically_derived] - impl ::core::cmp::Eq for Test { - #[inline] - fn assert_receiver_is_total_eq(&self) { - struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); + 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>); - // For some reason the comparison fails without the extra space at the end. - let _: __AssertEq >; - let _: __AssertEq >; + // 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 { } #[automatically_derived] impl ::core::hash::Hash for Test { diff --git a/src/test/bound.rs b/src/test/bound.rs index a26658c8..c9bcfb49 100644 --- a/src/test/bound.rs +++ b/src/test/bound.rs @@ -235,19 +235,28 @@ 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 - { - #[inline] - 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 >; - } - } + { } #[automatically_derived] impl ::core::hash::Hash for Test @@ -377,21 +386,32 @@ 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 - { - #[inline] - 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 >; - } - } + { } #[automatically_derived] impl ::core::hash::Hash for Test diff --git a/src/test/zeroize.rs b/src/test/zeroize.rs index c3c1a725..53907796 100644 --- a/src/test/zeroize.rs +++ b/src/test/zeroize.rs @@ -52,13 +52,28 @@ fn drop() -> Result<()> { where T: ::zeroize::ZeroizeOnDrop { fn drop(&mut self) { - use ::zeroize::__internal::AssertZeroize; - use ::zeroize::__internal::AssertZeroizeOnDrop; + trait AssertZeroizeOnDrop { + fn __derive_where_zeroize_or_on_drop(self); + } + + impl AssertZeroizeOnDrop for &&mut T { + fn __derive_where_zeroize_or_on_drop(self) {} + } + + trait AssertZeroize { + fn __derive_where_zeroize_or_on_drop(&mut self); + } + + impl AssertZeroize for T { + fn __derive_where_zeroize_or_on_drop(&mut self) { + ::zeroize::Zeroize::zeroize(self); + } + } match self { Test(ref mut __field_0, ref mut __field_1) => { - __field_0.zeroize_or_on_drop(); - __field_1.zeroize_or_on_drop(); + __field_0.__derive_where_zeroize_or_on_drop(); + __field_1.__derive_where_zeroize_or_on_drop(); } } } @@ -92,13 +107,28 @@ fn both() -> Result<()> { where T: ::zeroize::ZeroizeOnDrop { fn drop(&mut self) { - use ::zeroize::__internal::AssertZeroize; - use ::zeroize::__internal::AssertZeroizeOnDrop; + trait AssertZeroizeOnDrop { + fn __derive_where_zeroize_or_on_drop(self); + } + + impl AssertZeroizeOnDrop for &&mut T { + fn __derive_where_zeroize_or_on_drop(self) {} + } + + trait AssertZeroize { + fn __derive_where_zeroize_or_on_drop(&mut self); + } + + impl AssertZeroize for T { + fn __derive_where_zeroize_or_on_drop(&mut self) { + ::zeroize::Zeroize::zeroize(self); + } + } match self { Test(ref mut __field_0, ref mut __field_1) => { - __field_0.zeroize_or_on_drop(); - __field_1.zeroize_or_on_drop(); + __field_0.__derive_where_zeroize_or_on_drop(); + __field_1.__derive_where_zeroize_or_on_drop(); } } } @@ -188,12 +218,27 @@ fn crate_drop() -> Result<()> { where T: zeroize_::ZeroizeOnDrop { fn drop(&mut self) { - use zeroize_::__internal::AssertZeroize; - use zeroize_::__internal::AssertZeroizeOnDrop; + trait AssertZeroizeOnDrop { + fn __derive_where_zeroize_or_on_drop(self); + } + + impl AssertZeroizeOnDrop for &&mut T { + fn __derive_where_zeroize_or_on_drop(self) {} + } + + trait AssertZeroize { + fn __derive_where_zeroize_or_on_drop(&mut self); + } + + impl AssertZeroize for T { + fn __derive_where_zeroize_or_on_drop(&mut self) { + zeroize_::Zeroize::zeroize(self); + } + } match self { Test(ref mut __field_0) => { - __field_0.zeroize_or_on_drop(); + __field_0.__derive_where_zeroize_or_on_drop(); } } } @@ -285,12 +330,27 @@ fn enum_skip_drop() -> Result<()> { #[automatically_derived] impl ::core::ops::Drop for Test { fn drop(&mut self) { - use ::zeroize::__internal::AssertZeroize; - use ::zeroize::__internal::AssertZeroizeOnDrop; + trait AssertZeroizeOnDrop { + fn __derive_where_zeroize_or_on_drop(self); + } + + impl AssertZeroizeOnDrop for &&mut T { + fn __derive_where_zeroize_or_on_drop(self) {} + } + + trait AssertZeroize { + fn __derive_where_zeroize_or_on_drop(&mut self); + } + + impl AssertZeroize for T { + fn __derive_where_zeroize_or_on_drop(&mut self) { + ::zeroize::Zeroize::zeroize(self); + } + } match self { Test::A(ref mut __field_0) => { - __field_0.zeroize_or_on_drop(); + __field_0.__derive_where_zeroize_or_on_drop(); } Test::B(ref mut __field_0) => { } } diff --git a/src/trait_.rs b/src/trait_.rs index e6ebf7f6..0147d481 100644 --- a/src/trait_.rs +++ b/src/trait_.rs @@ -292,8 +292,8 @@ pub trait TraitImpl: Deref { None } - /// Trait to implement. Only used for [`ZeroizeOnDrop`](https://docs.rs/zeroize/latest/zeroize/trait.ZeroizeOnDrop.html) - /// because it implements [`Drop`] and not itself. + /// Trait to implement. Only used by [`Eq`] and + /// [`ZeroizeOnDrop`](https://docs.rs/zeroize/latest/zeroize/trait.ZeroizeOnDrop.html). fn impl_item( &self, imp: &ImplGenerics<'_>, diff --git a/src/trait_/eq.rs b/src/trait_/eq.rs index ecd25433..f45aed9b 100644 --- a/src/trait_/eq.rs +++ b/src/trait_/eq.rs @@ -1,9 +1,10 @@ //! [`Eq`](trait@std::cmp::Eq) implementation. -use std::ops::Deref; +use std::{borrow::Cow, ops::Deref}; use proc_macro2::TokenStream; use quote::quote; +use syn::{Ident, ImplGenerics, Path, TypeGenerics, WhereClause}; use crate::{util, Data, DeriveTrait, DeriveWhere, Item, SplitGenerics, Trait, TraitImpl}; @@ -19,10 +20,37 @@ impl TraitImpl for Eq { DeriveTrait::Eq } - fn path(&self) -> syn::Path { + fn path(&self) -> Path { util::path_from_strs(&["core", "cmp", "Eq"]) } + fn additional_impl(&self) -> Option<(Path, TokenStream)> { + Some((self.path(), quote! {})) + } + + fn impl_item( + &self, + 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, @@ -31,8 +59,7 @@ impl TraitImpl for Eq { body: &TokenStream, ) -> TokenStream { quote! { - #[inline] - fn assert_receiver_is_total_eq(&self) { + fn assert(&self) { struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>); #body diff --git a/src/trait_/zeroize_on_drop.rs b/src/trait_/zeroize_on_drop.rs index cfb56351..95491dea 100644 --- a/src/trait_/zeroize_on_drop.rs +++ b/src/trait_/zeroize_on_drop.rs @@ -184,23 +184,28 @@ impl TraitImpl for ZeroizeOnDrop { } } } else { - let crate_ = self.crate_(); - let internal = util::path_segment("__internal"); - - let mut assert_zeroize = crate_.clone(); - assert_zeroize - .segments - .extend([internal.clone(), util::path_segment("AssertZeroize")]); - - let mut assert_zeroize_on_drop = crate_; - assert_zeroize_on_drop - .segments - .extend([internal, util::path_segment("AssertZeroizeOnDrop")]); + let zeroize = util::path_from_root_and_strs(self.crate_(), &["Zeroize"]); + let zeroize_on_drop = self.path(); quote! { fn drop(&mut self) { - use #assert_zeroize; - use #assert_zeroize_on_drop; + trait AssertZeroizeOnDrop { + fn __derive_where_zeroize_or_on_drop(self); + } + + impl AssertZeroizeOnDrop for &&mut T { + fn __derive_where_zeroize_or_on_drop(self) {} + } + + trait AssertZeroize { + fn __derive_where_zeroize_or_on_drop(&mut self); + } + + impl AssertZeroize for T { + fn __derive_where_zeroize_or_on_drop(&mut self) { + #zeroize::zeroize(self); + } + } match self { #body @@ -242,7 +247,7 @@ impl TraitImpl for ZeroizeOnDrop { } else { quote! { #self_pattern => { - #(#self_ident.zeroize_or_on_drop();)* + #(#self_ident.__derive_where_zeroize_or_on_drop();)* } } }