trait_bounds/lib.rs
1//! This nightly-only library provides useful primitives for defining trait bounds
2//!
3//! [`eq`] and [`ne`] functions allow to check whether two types are equal in a `const` context
4//!
5//! [`type_id`] is similar to [`core::intrinsics::type_id`], but it can be used on [`PointeeSized`](core::marker::PointeeSized) types
6//!
7//! [`Assert<true>`] implements [`IsTrue`]
8//!
9//! [`Assert<false>`] implements [`IsFalse`]
10//!
11//! [`Is<T>`] is implemented for `U` if and only if `U` is equal to `T`
12//!
13//! [`Not<T>`] is implemented for `U` if and only if `U` is not equal to `T`
14//!
15//! The [`Not`] trait can be used to define multiple blanket implementations, which is particularly useful with the [`From<T>`] trait,
16//! as [`From<T> for T`](From<T>#impl-From<T>-for-T) often collides with user-defined blanket impls
17//!
18//! ```
19#![doc = include_str!("../examples/from_many.rs")]
20//! ```
21//! ```
22#![doc = include_str!("../examples/somehow.rs")]
23//! ```
24#![no_std]
25#![expect(internal_features)]
26#![expect(incomplete_features)]
27#![feature(core_intrinsics)]
28#![feature(generic_const_exprs)]
29#![feature(fundamental)]
30#![feature(rustc_attrs)]
31#![feature(intrinsics)]
32#![rustc_no_implicit_bounds]
33
34use core::{any::TypeId, intrinsics::type_id_eq};
35
36/// Returns a [`TypeId`] of a given type
37///
38/// Unlike [`core::intrinsics::type_id`], this can be used on [`PointeeSized`](core::marker::PointeeSized) types
39#[must_use]
40#[rustc_nounwind]
41#[rustc_intrinsic]
42pub const fn type_id<T>() -> TypeId;
43
44/// Returns `true` if `This` and `Other` types are equal, `false` otherwise
45#[must_use]
46pub const fn eq<This, Other>() -> bool {
47 type_id_eq(type_id::<This>(), type_id::<Other>())
48}
49
50/// Returns `true` if `This` and `Other` types are not equal, `false` otherwise
51#[must_use]
52pub const fn ne<This, Other>() -> bool {
53 !eq::<This, Other>()
54}
55
56/// Implements [`IsTrue`] if and only if `COND` is `true`,
57/// implements [`IsFalse`] if and only if `COND` is `false`
58pub struct Assert<const COND: bool>;
59
60/// Trait used for [`Assert<bool>`] bounds, implemented by [`Assert<true>`] and not implemented by [`Assert<false>`]
61#[fundamental]
62pub trait IsTrue {}
63impl IsTrue for Assert<true> {}
64
65/// Trait used for [`Assert<bool>`] bounds, implemented by [`Assert<false>`] and not implemented by [`Assert<true>`]
66#[fundamental]
67pub trait IsFalse {}
68impl IsFalse for Assert<false> {}
69
70/// [`Is<T>`] is implemented for `U` if and only if `U` is equal to `T`
71#[fundamental]
72pub trait Is<T> {}
73impl<T> Is<T> for T {}
74
75/// [`Not<T>`] is implemented for `U` if and only if `U` is not equal to `T`
76#[fundamental]
77pub trait Not<T> {}
78impl<This, Other> Not<Other> for This where Assert<{ ne::<This, Other>() }>: IsTrue {}