macro_rules! assert_impl {
    (for($($generic:tt)*) $ty:ty: $($rest:tt)*) => { ... };
    ($ty:ty: $($rest:tt)*) => { ... };
}
Expand description

Asserts that the type implements a logical trait expression.

This macro causes a compilation failure if the expression is not satisfied.

See does_impl! for simply getting a bool from this condition without asserting it.

Syntax

assert_impl!(<type>: <trait_expr>);
assert_impl!(for(<type>: <bounds>) <type>: <trait_expr>);

where:

  • <type> is a type (that must not depend on a generic parameter)

  • <trait_expr> is an expression made out of trait names, combined with ! for negation, & for conjunction, | for disjunction and parentheses for grouping.

  • <bounds> is a trait bounds expression.

For technical reasons:

  • Traits (like Into<u8>) that are not a single identifier must be surrounded by parentheses.

  • The usual operator priority is not respected: x & y | z is parsed as x & (y | z).

Examples

If u32 were to implement Into conversions for usize and for u8, the following would fail to compile:

assert_impl!(u32: !((Into<usize>) & (Into<u8>)));

Check that a type is Send but not Sync.

use std::cell::Cell;

assert_impl!(Cell<u32>: Send & !Sync);

Check simple one-off cases:

assert_impl!(&'static mut u8: !Copy);

Check that a type is always Clone even when its parameter isn’t:

use std::rc::Rc;

assert_impl!(for(T) Rc<T>: Clone);

The following example fails to compile since u64 cannot be converted into either u32 or u16:

assert_impl!(u64: (Into<u32>) | (Into<u16>));