Skip to content

Commit

Permalink
Make assert_impl_one! work with all combinations
Browse files Browse the repository at this point in the history
Fixes the issue where subsequent traits were only checked against the
first trait and not to one another. This solution was made possible by
@SimonSapin demonstrating to me how to expand the input sequence into
combinations of inputs.

Closes #20.
  • Loading branch information
nvzqz committed Oct 18, 2019
1 parent f096b6d commit ea9ec5d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/assert_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,16 @@
macro_rules! assert_impl_one {
($type:ty: $t:path, $($ts:path),+ $(,)?) => {
assert_impl_any!($type: $t, $($ts),+);
// FIXME: Only works against the first trait; needs to check all
// subsequent traits against one another.
assert_impl_one!(_priv $type: $t, $($ts),+);
};
// Expands into all combinations of trait pairs to ensure `$type` does not
// implement any pair of traits.
(_priv $type:ty: $t:path, $($ts:path),+) => {
$(assert_not_impl_all!($type: $t, $ts);)+
assert_impl_one!(_priv $type: $($ts),+);
};
// Finished passing along pairs, nothing to do.
(_priv $type:ty: $t:path) => {};
}

/// Asserts that the type implements _all_ of the given traits.
Expand Down
17 changes: 17 additions & 0 deletions tests/trait_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,20 @@ assert_impl_all!(str: Send, Sync, AsRef<[u8]>,);
assert_impl_any!((): Send, Sync);
assert_impl_any!((): Send, From<u8>);
assert_impl_any!((): From<u8>, From<u16>, Send);

#[allow(dead_code)]
struct Foo;

trait A {}
trait B {}
trait C {}

impl B for Foo {}

assert_impl_one!(Foo: A, B);
assert_impl_one!(Foo: B, A);
assert_impl_one!(Foo: B, C);
assert_impl_one!(Foo: C, B);
assert_impl_one!(Foo: A, B, C);
assert_impl_one!(Foo: B, C, A);
assert_impl_one!(Foo: C, A, B);

0 comments on commit ea9ec5d

Please sign in to comment.