type_equals/
lib.rs

1//! A trait for checking type equality.
2//!
3//! This crate implements the TypeEquals trick described in [rust-lang/rust#20041][comment].
4//!
5//! The following compiles:
6//!
7//! ```
8//! use type_equals::TypeEquals;
9//!
10//! pub trait Owner {
11//!     type Child1: Child;
12//!     type Child2: Child;
13//! }
14//!
15//! pub trait Child {
16//!     type Owner: Owner;
17//! }
18//!
19//! pub struct A;
20//! impl Owner for A {
21//!     type Child1 = B;
22//!     type Child2 = C;
23//! }
24//!
25//! pub struct B;
26//! impl Child for B {
27//!     type Owner = A;
28//! }
29//!
30//! pub struct C;
31//! impl Child for C {
32//!     type Owner = A;
33//! }
34//!
35//! pub fn want_child_one<T: Child>()
36//! where
37//!     <T::Owner as Owner>::Child1: TypeEquals<Other = T>,
38//! {}
39//!
40//! pub fn want_child_two<T: Child>()
41//! where
42//!     <T::Owner as Owner>::Child2: TypeEquals<Other = T>,
43//! {}
44//!
45//! pub fn this_works() {
46//!     want_child_one::<B>();
47//!     want_child_two::<C>();
48//! }
49//! ```
50//!
51//! Meanwhile, the following does not compile:
52//! ```compile_fail
53//! // A, B, C, want_child_one and want_child_two are declared identically.
54//!
55//! # use type_equals::TypeEquals;
56//! #
57//! # pub trait Owner {
58//! #     type Child1: Child;
59//! #     type Child2: Child;
60//! # }
61//! #
62//! # pub trait Child {
63//! #     type Owner: Owner;
64//! # }
65//! #
66//! # pub struct A;
67//! # impl Owner for A {
68//! #     type Child1 = B;
69//! #     type Child2 = C;
70//! # }
71//! #
72//! # pub struct B;
73//! # impl Child for B {
74//! #     type Owner = A;
75//! # }
76//! #
77//! # pub struct C;
78//! # impl Child for C {
79//! #     type Owner = A;
80//! # }
81//! #
82//! # pub fn want_child_one<T: Child>()
83//! # where
84//! #     <T::Owner as Owner>::Child1: TypeEquals<Other = T>,
85//! # {}
86//! #
87//! # pub fn want_child_two<T: Child>()
88//! # where
89//! #     <T::Owner as Owner>::Child2: TypeEquals<Other = T>,
90//! # {}
91//! #
92//! pub fn this_does_not_work() {
93//!     want_child_one::<C>();
94//!     want_child_two::<B>();
95//! }
96//! ```
97//!
98//!   [comment]: https://github.com/rust-lang/rust/issues/20041#issuecomment-564369542.
99pub trait TypeEquals {
100    type Other: ?Sized;
101}
102
103impl<T: ?Sized> TypeEquals for T {
104    type Other = Self;
105}