summaryrefslogtreecommitdiffstats
path: root/vendor/static_assertions/src/assert_type.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/static_assertions/src/assert_type.rs')
-rw-r--r--vendor/static_assertions/src/assert_type.rs101
1 files changed, 101 insertions, 0 deletions
diff --git a/vendor/static_assertions/src/assert_type.rs b/vendor/static_assertions/src/assert_type.rs
new file mode 100644
index 000000000..dd2dc2a6f
--- /dev/null
+++ b/vendor/static_assertions/src/assert_type.rs
@@ -0,0 +1,101 @@
+/// Asserts that _all_ types in a list are equal to each other.
+///
+/// # Examples
+///
+/// Often times, type aliases are used to express usage semantics via naming. In
+/// some cases, the underlying type may differ based on platform. However, other
+/// types like [`c_float`] will always alias the same type.
+///
+/// ```
+/// # #[macro_use] extern crate static_assertions; fn main() {}
+/// use std::os::raw::c_float;
+///
+/// assert_type_eq_all!(c_float, f32);
+/// ```
+///
+/// This macro can also be used to compare types that involve lifetimes! Just
+/// use `'static` in that case:
+///
+/// ```
+/// # #[macro_use] extern crate static_assertions;
+/// # fn main() {
+/// type Buf<'a> = &'a [u8];
+///
+/// assert_type_eq_all!(Buf<'static>, &'static [u8]);
+/// # }
+/// ```
+///
+/// The following example fails to compile because `String` and `str` do not
+/// refer to the same type:
+///
+/// ```compile_fail
+/// # #[macro_use] extern crate static_assertions; fn main() {}
+/// assert_type_eq_all!(String, str);
+/// ```
+///
+/// This should also work the other way around, regardless of [`Deref`]
+/// implementations.
+///
+/// ```compile_fail
+/// # #[macro_use] extern crate static_assertions; fn main() {}
+/// assert_type_eq_all!(str, String);
+/// ```
+///
+/// [`c_float`]: https://doc.rust-lang.org/std/os/raw/type.c_float.html
+/// [`Deref`]: https://doc.rust-lang.org/std/ops/trait.Deref.html
+#[macro_export]
+macro_rules! assert_type_eq_all {
+ ($x:ty, $($xs:ty),+ $(,)*) => {
+ const _: fn() = || { $({
+ trait TypeEq {
+ type This: ?Sized;
+ }
+
+ impl<T: ?Sized> TypeEq for T {
+ type This = Self;
+ }
+
+ fn assert_type_eq_all<T, U>()
+ where
+ T: ?Sized + TypeEq<This = U>,
+ U: ?Sized,
+ {}
+
+ assert_type_eq_all::<$x, $xs>();
+ })+ };
+ };
+}
+
+/// Asserts that _all_ types are **not** equal to each other.
+///
+/// # Examples
+///
+/// Rust has all sorts of slices, but they represent different types of data:
+///
+/// ```
+/// # #[macro_use] extern crate static_assertions; fn main() {}
+/// assert_type_ne_all!([u8], [u16], str);
+/// ```
+///
+/// The following example fails to compile because [`c_uchar`] is a type alias
+/// for [`u8`]:
+///
+/// ```compile_fail
+/// # #[macro_use] extern crate static_assertions; fn main() {}
+/// use std::os::raw::c_uchar;
+///
+/// assert_type_ne_all!(c_uchar, u8, u32);
+/// ```
+///
+/// [`c_uchar`]: https://doc.rust-lang.org/std/os/raw/type.c_uchar.html
+/// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
+#[macro_export]
+macro_rules! assert_type_ne_all {
+ ($x:ty, $($y:ty),+ $(,)?) => {
+ const _: fn() = || {
+ trait MutuallyExclusive {}
+ impl MutuallyExclusive for $x {}
+ $(impl MutuallyExclusive for $y {})+
+ };
+ };
+}