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)* > )?)*
) => { ... };
}Expand description
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));ⓘ
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);