Skip to content

Commit c2e4959

Browse files
authored
Generate shortcut for Clone and Ord only when all generics are custom bound (#137)
* Generate shortcut for Clone and Ord only when all generics are custom bound * Formatting fixed * unicode-ident pinning for CI tests * Addition version pinning in CI * Updated UI test on nightly * Updated ui test for zeroize-on-drop
1 parent 7f47d61 commit c2e4959

7 files changed

Lines changed: 40 additions & 17 deletions

File tree

.github/workflows/test.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ jobs:
6767
cargo update -p glob --precise 0.3.2
6868
cargo update -p proc-macro2 --precise 1.0.80
6969
cargo update -p quote --precise 1.0.35
70+
cargo update -p unicode-ident --precise 1.0.22
71+
cargo update -p ryu --precise 1.0.20
72+
cargo update -p itoa --precise 1.0.15
7073
- name: Build
7174
run:
7275
cargo build --workspace ${{ matrix.features }}
@@ -130,6 +133,9 @@ jobs:
130133
cargo update -p pretty_assertions --precise 1.4.0
131134
cargo update -p proc-macro2 --precise 1.0.80
132135
cargo update -p quote --precise 1.0.35
136+
cargo update -p unicode-ident --precise 1.0.22
137+
cargo update -p ryu --precise 1.0.20
138+
cargo update -p itoa --precise 1.0.15
133139
- name: Build
134140
run:
135141
cargo build --target thumbv6m-none-eabi ${{ matrix.features }} -p ensure-no-std

src/attr/item.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,15 @@ impl DeriveWhere {
238238
})
239239
}
240240

241+
/// Returns `true` if all [`Generic`] are
242+
/// [`CustomBound`](Generic::CustomBound)
243+
pub fn all_custom_bound(&self) -> bool {
244+
self.generics.iter().all(|generic| match generic {
245+
Generic::CustomBound(_) => true,
246+
Generic::NoBound(_) => false,
247+
})
248+
}
249+
241250
/// Returns `true` if the given generic type parameter if present.
242251
pub fn has_type_param(&self, type_param: &Ident) -> bool {
243252
self.generics.iter().any(|generic| match generic {

src/trait_/clone.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ impl TraitImpl for Clone {
5757
body: &TokenStream,
5858
) -> TokenStream {
5959
// Special implementation for items also implementing `Copy`.
60-
if (derive_where.generics.is_empty() || derive_where.any_custom_bound())
61-
&& derive_where.contains(Trait::Copy)
62-
{
60+
if (derive_where.all_custom_bound()) && derive_where.contains(Trait::Copy) {
6361
return quote! {
6462
#[inline]
6563
fn clone(&self) -> Self { *self }
@@ -93,9 +91,7 @@ impl TraitImpl for Clone {
9391
}
9492

9593
fn build_body(&self, derive_where: &DeriveWhere, data: &Data) -> TokenStream {
96-
if (derive_where.generics.is_empty() || derive_where.any_custom_bound())
97-
&& derive_where.contains(Trait::Copy)
98-
{
94+
if (derive_where.all_custom_bound()) && derive_where.contains(Trait::Copy) {
9995
return TokenStream::new();
10096
}
10197

src/trait_/partial_ord.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ impl TraitImpl for PartialOrd {
3333
generics: &SplitGenerics<'_>,
3434
body: &TokenStream,
3535
) -> TokenStream {
36-
let body = if (derive_where.generics.is_empty() || derive_where.any_custom_bound())
37-
&& derive_where.contains(Trait::Ord)
38-
{
36+
let body = if (derive_where.all_custom_bound()) && derive_where.contains(Trait::Ord) {
3937
quote! {
4038
::core::option::Option::Some(::core::cmp::Ord::cmp(self, __other))
4139
}
@@ -54,8 +52,7 @@ impl TraitImpl for PartialOrd {
5452
fn build_body(&self, derive_where: &DeriveWhere, data: &Data) -> TokenStream {
5553
if data.is_empty(**self)
5654
|| data.is_incomparable()
57-
|| ((derive_where.generics.is_empty() || derive_where.any_custom_bound())
58-
&& derive_where.contains(Trait::Ord))
55+
|| (derive_where.all_custom_bound() && derive_where.contains(Trait::Ord))
5956
{
6057
TokenStream::new()
6158
} else {

tests/bound.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,17 @@ fn ord_requirement() {
8181
#[derive_where(Eq, Ord, PartialEq, PartialOrd; T::Type)]
8282
struct Test<T: Trait>(T::Type);
8383
}
84+
85+
#[test]
86+
fn ord_and_partial_ord() {
87+
trait Trait {}
88+
#[derive_where(PartialOrd, Ord, PartialEq, Eq; I: Trait, T)]
89+
struct Foo<T, I>(T, PhantomData<I>);
90+
}
91+
92+
#[test]
93+
fn copy_and_clone() {
94+
trait Trait {}
95+
#[derive_where(Copy, Clone; I: Trait, T)]
96+
struct Foo<T, I>(T, PhantomData<I>);
97+
}

tests/ui/union.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ error: traits other then `Clone` and `Copy` aren't supported by unions
66
8 | | }
77
| |_^
88

9-
error[E0277]: the trait bound `MissingCopy<T>: std::marker::Copy` is not satisfied
9+
error[E0277]: the trait bound `MissingCopy<T>: Copy` is not satisfied
1010
--> tests/ui/union.rs:10:1
1111
|
1212
10 | #[derive_where(Clone)]
13-
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `MissingCopy<T>`
13+
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `MissingCopy<T>`
1414
|
1515
note: required by a bound in `__AssertCopy`
1616
--> tests/ui/union.rs:10:1

tests/ui/zeroize-on-drop/zeroize-on-drop.stderr

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ note: the following trait bounds were not satisfied:
1616
--> tests/ui/zeroize-on-drop/zeroize-on-drop.rs:10:1
1717
|
1818
10 | #[derive_where(ZeroizeOnDrop(no_drop))]
19-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter would need to implement `AssertZeroizeOnDrop`
20+
= help: consider manually implementing the trait to avoid undesired bounds
2021
= help: items from traits can only be used if the type parameter is bounded by the trait
21-
= note: this error originates in the derive macro `::derive_where::DeriveWhere` which comes from the expansion of the attribute macro `derive_where` (in Nightly builds, run with -Z macro-backtrace for more info)
22+
= note: this error originates in the derive macro `::derive_where::DeriveWhere` (in Nightly builds, run with -Z macro-backtrace for more info)
2223
help: the following trait defines an item `__derive_where_zeroize_on_drop`, perhaps you need to restrict type parameter `T` with it:
2324
|
24-
11 | struct NoDropNoZeroizeOnDrop<T: <NoDropNoZeroizeOnDrop<T> as DeriveWhereAssertZeroizeOnDrop>::assert::AssertZeroizeOnDrop>(T);
25-
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
25+
11 | struct NoDropNoZeroizeOnDrop<T: AssertZeroizeOnDrop>(T);
26+
| +++++++++++++++++++++

0 commit comments

Comments
 (0)