1 // Traits:
2 
3 pub trait Alpha {
alpha(self) -> usize4     fn alpha(self) -> usize;
5 }
6 
7 pub trait Beta {
8     type Gamma;
gamma(&self) -> Self::Gamma9     fn gamma(&self) -> Self::Gamma;
10 }
11 
12 pub trait Delta {
delta(self) -> usize13     fn delta(self) -> usize;
14 }
15 
16 pub trait Epsilon<'a> {
17     type Zeta;
zeta(&'a self) -> Self::Zeta18     fn zeta(&'a self) -> Self::Zeta;
19 
epsilon(&'a self) -> usize20     fn epsilon(&'a self) -> usize;
21 }
22 
23 pub trait Eta {
eta(self) -> usize24     fn eta(self) -> usize;
25 }
26 
27 // Assertions:
28 
assert_alpha<T: Alpha>(x: T) -> usize29 pub fn assert_alpha<T: Alpha>(x: T) -> usize { x.alpha() }
assert_static<T: 'static>(_: T) -> usize30 pub fn assert_static<T: 'static>(_: T) -> usize { 24 }
assert_delta<T: Delta>(x: T) -> usize31 pub fn assert_delta<T: Delta>(x: T) -> usize { x.delta() }
assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize32 pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() }
assert_epsilon_forall<T: for<'a> Epsilon<'a>>()33 pub fn assert_epsilon_forall<T: for<'a> Epsilon<'a>>() {}
assert_forall_epsilon_zeta_satisfies_eta<T>(x: T) -> usize where T: for<'a> Epsilon<'a>, for<'a> <T as Epsilon<'a>>::Zeta: Eta,34 pub fn assert_forall_epsilon_zeta_satisfies_eta<T>(x: T) -> usize
35 where
36     T: for<'a> Epsilon<'a>,
37     for<'a> <T as Epsilon<'a>>::Zeta: Eta,
38 {
39     x.epsilon() + x.zeta().eta()
40 }
41 
42 // Implementations and types:
43 
44 #[derive(Copy, Clone)]
45 pub struct BetaType;
46 
47 #[derive(Copy, Clone)]
48 pub struct GammaType;
49 
50 #[derive(Copy, Clone)]
51 pub struct ZetaType;
52 
53 impl<T> Beta for &(dyn Beta<Gamma = T> + Send) {
54     type Gamma = T;
gamma(&self) -> Self::Gamma55     fn gamma(&self) -> Self::Gamma { (*self).gamma() }
56 }
57 
58 impl Beta for BetaType {
59     type Gamma = GammaType;
gamma(&self) -> Self::Gamma60     fn gamma(&self) -> Self::Gamma { GammaType }
61 }
62 
63 impl<'a> Beta for &'a BetaType {
64     type Gamma = GammaType;
gamma(&self) -> Self::Gamma65     fn gamma(&self) -> Self::Gamma { GammaType }
66 }
67 
68 impl Beta for GammaType {
69     type Gamma = Self;
gamma(&self) -> Self::Gamma70     fn gamma(&self) -> Self::Gamma { Self }
71 }
72 
73 impl Alpha for GammaType {
alpha(self) -> usize74     fn alpha(self) -> usize { 42 }
75 }
76 
77 impl Delta for GammaType {
delta(self) -> usize78     fn delta(self) -> usize { 1337 }
79 }
80 
81 impl<'a> Epsilon<'a> for GammaType {
82     type Zeta = ZetaType;
zeta(&'a self) -> Self::Zeta83     fn zeta(&'a self) -> Self::Zeta { ZetaType }
84 
epsilon(&'a self) -> usize85     fn epsilon(&'a self) -> usize { 7331 }
86 }
87 
88 impl Eta for ZetaType {
eta(self) -> usize89     fn eta(self) -> usize { 7 }
90 }
91 
92 // Desugared forms to check against:
93 
desugared_bound<B: ?Sized>(beta: &B) -> usize where B: Beta, B::Gamma: Alpha94 pub fn desugared_bound<B: ?Sized>(beta: &B) -> usize
95 where
96     B: Beta,
97     B::Gamma: Alpha
98 {
99     let gamma: B::Gamma = beta.gamma();
100     assert_alpha::<B::Gamma>(gamma)
101 }
102 
desugared_bound_region<B: ?Sized>(beta: &B) -> usize where B: Beta, B::Gamma: 'static,103 pub fn desugared_bound_region<B: ?Sized>(beta: &B) -> usize
104 where
105     B: Beta,
106     B::Gamma: 'static,
107 {
108     assert_static::<B::Gamma>(beta.gamma())
109 }
110 
desugared_bound_multi<B: ?Sized>(beta: B) -> usize where B: Copy + Beta, B::Gamma: Alpha + 'static + Delta,111 pub fn desugared_bound_multi<B: ?Sized>(beta: B) -> usize
112 where
113     B: Copy + Beta,
114     B::Gamma: Alpha + 'static + Delta,
115 {
116     assert_alpha::<B::Gamma>(beta.gamma()) +
117     assert_static::<B::Gamma>(beta.gamma()) +
118     assert_delta::<B::Gamma>(beta.gamma())
119 }
120 
desugared_bound_region_specific<'a, B: ?Sized>(gamma: &'a B::Gamma) -> usize where B: Beta, B::Gamma: 'a + Epsilon<'a>,121 pub fn desugared_bound_region_specific<'a, B: ?Sized>(gamma: &'a B::Gamma) -> usize
122 where
123     B: Beta,
124     B::Gamma: 'a + Epsilon<'a>,
125 {
126     assert_epsilon_specific::<B::Gamma>(gamma)
127 }
128 
desugared_bound_region_forall<B: ?Sized>(beta: &B) -> usize where B: Beta, B::Gamma: Copy + for<'a> Epsilon<'a>,129 pub fn desugared_bound_region_forall<B: ?Sized>(beta: &B) -> usize
130 where
131     B: Beta,
132     B::Gamma: Copy + for<'a> Epsilon<'a>,
133 {
134     assert_epsilon_forall::<B::Gamma>();
135     let g1: B::Gamma = beta.gamma();
136     let g2: B::Gamma = g1;
137     assert_epsilon_specific::<B::Gamma>(&g1) +
138     assert_epsilon_specific::<B::Gamma>(&g2)
139 }
140 
desugared_bound_region_forall2<B: ?Sized>(beta: &B) -> usize where B: Beta, B::Gamma: Copy + for<'a> Epsilon<'a>, for<'a> <B::Gamma as Epsilon<'a>>::Zeta: Eta,141 pub fn desugared_bound_region_forall2<B: ?Sized>(beta: &B) -> usize
142 where
143     B: Beta,
144     B::Gamma: Copy + for<'a> Epsilon<'a>,
145     for<'a> <B::Gamma as Epsilon<'a>>::Zeta: Eta,
146 {
147     let gamma = beta.gamma();
148     assert_forall_epsilon_zeta_satisfies_eta::<B::Gamma>(gamma)
149 }
150 
desugared_contraint_region_forall<B: ?Sized>(beta: &B) -> usize where for<'a> &'a B: Beta, for<'a> <&'a B as Beta>::Gamma: Alpha,151 pub fn desugared_contraint_region_forall<B: ?Sized>(beta: &B) -> usize
152 where
153     for<'a> &'a B: Beta,
154     for<'a> <&'a B as Beta>::Gamma: Alpha,
155 {
156     let g1 = beta.gamma();
157     let g2 = beta.gamma();
158     assert_alpha(g1) + assert_alpha(g2)
159 }
160 
desugared_bound_nested<B: ?Sized>(beta: &B) -> usize where B: Beta, B::Gamma: Copy + Alpha + Beta, <B::Gamma as Beta>::Gamma: Delta,161 pub fn desugared_bound_nested<B: ?Sized>(beta: &B) -> usize
162 where
163     B: Beta,
164     B::Gamma: Copy + Alpha + Beta,
165     <B::Gamma as Beta>::Gamma: Delta,
166 {
167     let go = beta.gamma();
168     let gi = go.gamma();
169     go.alpha() + gi.delta()
170 }
171 
desugared()172 pub fn desugared() {
173     let beta = BetaType;
174     let gamma = beta.gamma();
175 
176     assert_eq!(42, desugared_bound(&beta));
177     assert_eq!(24, desugared_bound_region(&beta));
178     assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta));
179     assert_eq!(7331, desugared_bound_region_specific::<BetaType>(&gamma));
180     assert_eq!(7331 * 2, desugared_bound_region_forall(&beta));
181     assert_eq!(42 + 1337, desugared_bound_nested(&beta));
182 }
183