assert_type_eq/
lib.rs

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