Skip to content
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
6 changes: 6 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ jobs:
cargo update -p glob --precise 0.3.2
cargo update -p proc-macro2 --precise 1.0.80
cargo update -p quote --precise 1.0.35
cargo update -p unicode-ident --precise 1.0.22
cargo update -p ryu --precise 1.0.20
cargo update -p itoa --precise 1.0.15
- name: Build
run:
cargo build --workspace ${{ matrix.features }}
Expand Down Expand Up @@ -130,6 +133,9 @@ jobs:
cargo update -p pretty_assertions --precise 1.4.0
cargo update -p proc-macro2 --precise 1.0.80
cargo update -p quote --precise 1.0.35
cargo update -p unicode-ident --precise 1.0.22
cargo update -p ryu --precise 1.0.20
cargo update -p itoa --precise 1.0.15
- name: Build
run:
cargo build --target thumbv6m-none-eabi ${{ matrix.features }} -p ensure-no-std
Expand Down
9 changes: 9 additions & 0 deletions src/attr/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ impl DeriveWhere {
})
}

/// Returns `true` if all [`Generic`] are
/// [`CustomBound`](Generic::CustomBound)
pub fn all_custom_bound(&self) -> bool {
self.generics.iter().all(|generic| match generic {
Generic::CustomBound(_) => true,
Generic::NoBound(_) => false,
})
}

/// Returns `true` if the given generic type parameter if present.
pub fn has_type_param(&self, type_param: &Ident) -> bool {
self.generics.iter().any(|generic| match generic {
Expand Down
8 changes: 2 additions & 6 deletions src/trait_/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ impl TraitImpl for Clone {
body: &TokenStream,
) -> TokenStream {
// Special implementation for items also implementing `Copy`.
if (derive_where.generics.is_empty() || derive_where.any_custom_bound())
&& derive_where.contains(Trait::Copy)
{
if (derive_where.all_custom_bound()) && derive_where.contains(Trait::Copy) {
return quote! {
#[inline]
fn clone(&self) -> Self { *self }
Expand Down Expand Up @@ -93,9 +91,7 @@ impl TraitImpl for Clone {
}

fn build_body(&self, derive_where: &DeriveWhere, data: &Data) -> TokenStream {
if (derive_where.generics.is_empty() || derive_where.any_custom_bound())
&& derive_where.contains(Trait::Copy)
{
if (derive_where.all_custom_bound()) && derive_where.contains(Trait::Copy) {
return TokenStream::new();
}

Expand Down
7 changes: 2 additions & 5 deletions src/trait_/partial_ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ impl TraitImpl for PartialOrd {
generics: &SplitGenerics<'_>,
body: &TokenStream,
) -> TokenStream {
let body = if (derive_where.generics.is_empty() || derive_where.any_custom_bound())
&& derive_where.contains(Trait::Ord)
{
let body = if (derive_where.all_custom_bound()) && derive_where.contains(Trait::Ord) {
quote! {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, __other))
}
Expand All @@ -54,8 +52,7 @@ impl TraitImpl for PartialOrd {
fn build_body(&self, derive_where: &DeriveWhere, data: &Data) -> TokenStream {
if data.is_empty(**self)
|| data.is_incomparable()
|| ((derive_where.generics.is_empty() || derive_where.any_custom_bound())
&& derive_where.contains(Trait::Ord))
|| (derive_where.all_custom_bound() && derive_where.contains(Trait::Ord))
{
TokenStream::new()
} else {
Expand Down
14 changes: 14 additions & 0 deletions tests/bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,17 @@ fn ord_requirement() {
#[derive_where(Eq, Ord, PartialEq, PartialOrd; T::Type)]
struct Test<T: Trait>(T::Type);
}

#[test]
fn ord_and_partial_ord() {
trait Trait {}
#[derive_where(PartialOrd, Ord, PartialEq, Eq; I: Trait, T)]
struct Foo<T, I>(T, PhantomData<I>);
}

#[test]
fn copy_and_clone() {
trait Trait {}
#[derive_where(Copy, Clone; I: Trait, T)]
struct Foo<T, I>(T, PhantomData<I>);
}
4 changes: 2 additions & 2 deletions tests/ui/union.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ error: traits other then `Clone` and `Copy` aren't supported by unions
8 | | }
| |_^

error[E0277]: the trait bound `MissingCopy<T>: std::marker::Copy` is not satisfied
error[E0277]: the trait bound `MissingCopy<T>: Copy` is not satisfied
--> tests/ui/union.rs:10:1
|
10 | #[derive_where(Clone)]
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `MissingCopy<T>`
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `MissingCopy<T>`
|
note: required by a bound in `__AssertCopy`
--> tests/ui/union.rs:10:1
Expand Down
9 changes: 5 additions & 4 deletions tests/ui/zeroize-on-drop/zeroize-on-drop.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ note: the following trait bounds were not satisfied:
--> tests/ui/zeroize-on-drop/zeroize-on-drop.rs:10:1
|
10 | #[derive_where(ZeroizeOnDrop(no_drop))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter would need to implement `AssertZeroizeOnDrop`
= help: consider manually implementing the trait to avoid undesired bounds
= help: items from traits can only be used if the type parameter is bounded by the trait
= 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)
= note: this error originates in the derive macro `::derive_where::DeriveWhere` (in Nightly builds, run with -Z macro-backtrace for more info)
help: the following trait defines an item `__derive_where_zeroize_on_drop`, perhaps you need to restrict type parameter `T` with it:
|
11 | struct NoDropNoZeroizeOnDrop<T: <NoDropNoZeroizeOnDrop<T> as DeriveWhereAssertZeroizeOnDrop>::assert::AssertZeroizeOnDrop>(T);
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 | struct NoDropNoZeroizeOnDrop<T: AssertZeroizeOnDrop>(T);
| +++++++++++++++++++++