[][src]Macro assert_bound::as_opaque

macro_rules! as_opaque {
    (
        $e:expr =>
        // One trait bound, e.g. `std::fmt::Debug`, `PartialEq<()>`
        $head:ident $( :: $tail:ident )* $( < $param:ty $(, $p:ty)* > )?
        // Zero or more trait bounds splited by `+`
        $(+ $head2:ident $( :: $tail2:ident )* $( < $param2:ty $(, $p2:ty)* > )?)*
        // lifetime
        ; $lifetime:tt
    ) => { ... };
    (
        $e:expr =>
        // One trait bound, e.g. `std::fmt::Debug`, `PartialEq<()>`
        $head:ident $( :: $tail:ident )* $( < $param:ty $(, $p:ty)* > )?
        // Zero or more trait bounds splited by `+`
        $(+ $head2:ident $( :: $tail2:ident )* $( < $param2:ty $(, $p2:ty)* > )?)*
    ) => { ... };
}

Cast type to opaque type that implements trait(s) (impl Trait + Trait2)


println!("{:?}", as_opaque!(() => std::fmt::Debug)); // `as_opaque!` return `impl Debug`
let t = as_opaque!(() => PartialEq<()> + PartialOrd<()>);

assert!(t == ());
assert_eq!(t.partial_cmp(&()), Some(std::cmp::Ordering::Equal));
This example deliberately fails to compile
assert_bound!(&(), Eq); // OK
assert_bound!(&as_opaque!((); Ord), Ord); // OK
assert_bound!(&as_opaque!((); Ord), Eq); // Error

Expand

Following code:

as_opaque!(() => PartialEq<()> + PartialOrd<()>);

expands to something like this:

fn as_opaque<T>(expr: T) -> impl PartialEq<()> + PartialOrd<()> + 'static
where
    T: PartialEq<()>,
    T: PartialOrd<()>,
    T: 'static,
{
    expr
}

let expr = ();
as_opaque(expr);