assert_type_eq/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
//! Statically assert that types from potentially different crate versions via
//! different dependencies are identical.
//!
//! Until RFC 1977 (public dependencies) is accepted, the situation where
//! multiple different versions of the same crate are present is possible. In
//! most situations this will simply cause code to not compile, as types
//! mismatch, however with runtime structures like `TypeMap` this leads to
//! runtime errors (often silent!) instead. This macro allows compile-time
//! assertion that types via different dependencies are identical, and will
//! interoperate, which is easier to debug than runtime errors.
//!
//! Usage:
//!
//! ```
//! #[macro_use]
//! extern crate assert_type_eq;
//!
//! pub mod my_crate {
//! pub struct MyStruct;
//! }
//!
//! mod a {
//! pub use super::my_crate;
//! }
//!
//! mod b {
//! pub use super::my_crate;
//! }
//!
//! assert_type_eq!(
//! my_crate::MyStruct,
//! a::my_crate::MyStruct,
//! b::my_crate::MyStruct,
//! );
//!
//! fn main() {
//! // ...
//! }
//! ```
//!
//! Specify all versions of the same type via different dependencies. Any types
//! that do not match the first type in the macro will cause a compile-time
//! error.
#[macro_export]
macro_rules! assert_type_eq {
( $t:ty, $( $ot:ty ),* $(,)* ) => {
mod assert_type_eq_mod {
#[allow(unused_imports)]
use super::*;
struct MatchingType<T>(T);
#[allow(dead_code, unreachable_patterns)]
fn assert_type_eq(mine: MatchingType<$t>) {
match mine {
$( MatchingType::<$ot>(_) => () ),*
}
}
}
}
}