Skip to content

Stop Using Internal APIs #116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .config/topic.dic
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
18
19
≥1
APIs
Changelog
CHANGELOG
derive_bounded
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
71 changes: 46 additions & 25 deletions src/test/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,23 @@ fn struct_() -> Result<()> {
}
}

#[automatically_derived]
impl<T> ::core::cmp::Eq for Test<T> {
#[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<std::marker::PhantomData<T> >;
impl<T> DeriveWhereAssertEq for Test<T> {
fn assert(&self) {
struct __AssertEq<__T: ::core::cmp::Eq + ?::core::marker::Sized>(::core::marker::PhantomData<__T>);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at some point we could consider creating our own types for stuff like that, though that'd require a non procmacro crate

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to #25.


// For some reason the comparison fails without the extra space at the end.
let _: __AssertEq<std::marker::PhantomData<T> >;
}
}
}
};

#[automatically_derived]
impl<T> ::core::cmp::Eq for Test<T> { }

#[automatically_derived]
impl<T> ::core::hash::Hash for Test<T> {
Expand Down Expand Up @@ -141,16 +148,23 @@ fn tuple() -> Result<()> {
}
}

#[automatically_derived]
impl<T> ::core::cmp::Eq for Test<T> {
#[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<T> DeriveWhereAssertEq for Test<T> {
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<std::marker::PhantomData<T> >;
// For some reason the comparison fails without the extra space at the end.
let _: __AssertEq<std::marker::PhantomData<T> >;
}
}
}
};

#[automatically_derived]
impl<T> ::core::cmp::Eq for Test<T> { }

#[automatically_derived]
impl<T> ::core::hash::Hash for Test<T> {
Expand Down Expand Up @@ -287,17 +301,24 @@ fn enum_() -> Result<()> {
}
}

#[automatically_derived]
impl<T> ::core::cmp::Eq for Test<T> {
#[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<T> DeriveWhereAssertEq for Test<T> {
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<std::marker::PhantomData<T> >;
let _: __AssertEq<std::marker::PhantomData<T> >;
// For some reason the comparison fails without the extra space at the end.
let _: __AssertEq<std::marker::PhantomData<T> >;
let _: __AssertEq<std::marker::PhantomData<T> >;
}
}
}
};

#[automatically_derived]
impl<T> ::core::cmp::Eq for Test<T> { }

#[automatically_derived]
impl<T> ::core::hash::Hash for Test<T> {
Expand Down
60 changes: 40 additions & 20 deletions src/test/bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,19 +235,28 @@ fn check_trait_bounds() -> Result<()> {
}
}

const _: () = {
trait DeriveWhereAssertEq {
fn assert(&self);
}

impl<T, U> DeriveWhereAssertEq for Test<T, U>
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<T >;
let _: __AssertEq<std::marker::PhantomData<U> >;
}
}
};

#[automatically_derived]
impl<T, U> ::core::cmp::Eq for Test<T, U>
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<T >;
let _: __AssertEq<std::marker::PhantomData<U> >;
}
}
{ }

#[automatically_derived]
impl<T, U> ::core::hash::Hash for Test<T, U>
Expand Down Expand Up @@ -377,21 +386,32 @@ fn check_multiple_trait_bounds() -> Result<()> {
}
}

const _: () = {
trait DeriveWhereAssertEq {
fn assert(&self);
}

impl<T, U, V> DeriveWhereAssertEq for Test<T, U, V>
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<T >;
let _: __AssertEq<std::marker::PhantomData<(U, V)> >;
}
}
};

#[automatically_derived]
impl<T, U, V> ::core::cmp::Eq for Test<T, U, V>
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<T >;
let _: __AssertEq<std::marker::PhantomData<(U, V)> >;
}
}
{ }

#[automatically_derived]
impl<T, U, V> ::core::hash::Hash for Test<T, U, V>
Expand Down
88 changes: 74 additions & 14 deletions src/test/zeroize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: ::zeroize::ZeroizeOnDrop + ?::core::marker::Sized> AssertZeroizeOnDrop for &&mut T {
fn __derive_where_zeroize_or_on_drop(self) {}
}

trait AssertZeroize {
fn __derive_where_zeroize_or_on_drop(&mut self);
}

impl<T: ::zeroize::Zeroize + ?::core::marker::Sized> 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();
}
}
}
Expand Down Expand Up @@ -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<T: ::zeroize::ZeroizeOnDrop + ?::core::marker::Sized> AssertZeroizeOnDrop for &&mut T {
fn __derive_where_zeroize_or_on_drop(self) {}
}

trait AssertZeroize {
fn __derive_where_zeroize_or_on_drop(&mut self);
}

impl<T: ::zeroize::Zeroize + ?::core::marker::Sized> 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();
}
}
}
Expand Down Expand Up @@ -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<T: zeroize_::ZeroizeOnDrop + ?::core::marker::Sized> AssertZeroizeOnDrop for &&mut T {
fn __derive_where_zeroize_or_on_drop(self) {}
}

trait AssertZeroize {
fn __derive_where_zeroize_or_on_drop(&mut self);
}

impl<T: zeroize_::Zeroize + ?::core::marker::Sized> 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();
}
}
}
Expand Down Expand Up @@ -285,12 +330,27 @@ fn enum_skip_drop() -> Result<()> {
#[automatically_derived]
impl <T> ::core::ops::Drop for Test<T> {
fn drop(&mut self) {
use ::zeroize::__internal::AssertZeroize;
use ::zeroize::__internal::AssertZeroizeOnDrop;
trait AssertZeroizeOnDrop {
fn __derive_where_zeroize_or_on_drop(self);
}

impl<T: ::zeroize::ZeroizeOnDrop + ?::core::marker::Sized> AssertZeroizeOnDrop for &&mut T {
fn __derive_where_zeroize_or_on_drop(self) {}
}

trait AssertZeroize {
fn __derive_where_zeroize_or_on_drop(&mut self);
}

impl<T: ::zeroize::Zeroize + ?::core::marker::Sized> 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) => { }
}
Expand Down
4 changes: 2 additions & 2 deletions src/trait_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ pub trait TraitImpl: Deref<Target = Trait> {
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<'_>,
Expand Down
35 changes: 31 additions & 4 deletions src/trait_/eq.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand All @@ -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<Cow<'_, WhereClause>>,
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,
Expand All @@ -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
Expand Down
Loading