same_types/lib.rs
1// Copyright (c) 2021 René Kijewski <rene.[SURNAME]@fu-berlin.de>
2// All rights reserved.
3//
4// This software and the accompanying materials are made available under
5// the terms of the ISC License which is available in the project root as LICENSE-ISC, AND/OR
6// the terms of the MIT License which is available at in the project root as LICENSE-MIT, AND/OR
7// the terms of the Apache License, Version 2.0 which is available in the project root as LICENSE-APACHE.
8//
9// You have to accept AT LEAST one of the aforementioned licenses to use, copy, modify, and/or distribute this software.
10// At your will you may redistribute the software under the terms of only one, two, or all three of the aforementioned licenses.
11
12#![forbid(unsafe_code)]
13#![deny(missing_docs)]
14#![no_std]
15
16//! Ensure that two types are the same, or fail with a compilation error.
17//!
18//! ```
19//! use same_types::assert_same_types;
20//!
21//! assert_same_types!(u32, u32, u32, u32);
22//! ```
23//!
24//! ```compile_fail
25//! use same_types::assert_same_types;
26//!
27//! // Fails with the message:
28//! // the trait `SameTypes` is not implemented for `(i32, u32)`
29//! assert_same_types!(u32, u32, i32, u32);
30//! ```
31
32use core::marker::PhantomData;
33
34/// Helper trait for [assert_same_types] to tell if two types are exactly the same.
35pub trait SameTypes {}
36
37impl<T> SameTypes for (T, T) {}
38
39/// Helper function for [assert_same_types] to tell if two types are exactly the same.
40#[doc(hidden)]
41#[inline(always)]
42pub const fn same_types<A, B>(_: PhantomData<*const A>, _: PhantomData<*const B>)
43where
44 (A, B): SameTypes,
45{
46}
47
48/// Assert that two or more types are exactly the same. Compilation error otherwise.
49///
50/// ```
51/// use same_types::assert_same_types;
52///
53/// assert_same_types!(u32, u32, u32, u32);
54/// ```
55///
56/// ```compile_fail
57/// use same_types::assert_same_types;
58///
59/// assert_same_types!(u32, u32, i32, u32);
60/// ```
61#[macro_export]
62macro_rules! assert_same_types {
63 ($A:ty $(,)?) => {
64 };
65 ($A:ty, $B:ty $(,)?) => {
66 $crate::same_types::<$A, $B>(::core::marker::PhantomData, ::core::marker::PhantomData);
67 };
68 ($A:ty, $B:ty, $($C:ty),+ $(,)?) => {
69 $crate::assert_same_types!($A, $B);
70 $crate::assert_same_types!($B, $($C),+);
71 };
72}