]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/issue-82079.rs
Auto merge of #91255 - b-naber:normalization-ice, r=jackh276
[rust.git] / src / test / ui / associated-types / issue-82079.rs
1 // check-pass
2
3 mod convenience_operators {
4     use crate::{Op, Relation};
5     use std::ops::AddAssign;
6     use std::ops::Mul;
7
8     impl<C: Op> Relation<C> {
9         pub fn map<F: Fn(C::D) -> D2 + 'static, D2: 'static>(
10             self,
11             f: F,
12         ) -> Relation<impl Op<D = D2, R = C::R>> {
13             self.map_dr(move |x, r| (f(x), r))
14         }
15     }
16
17     impl<K: 'static, V: 'static, C: Op<D = (K, V)>> Relation<C> {
18         pub fn semijoin<C2: Op<D = K, R = R2>, R2, R3: AddAssign<R3>>(
19             self,
20             other: Relation<C2>,
21         ) -> Relation<impl Op<D = C::D, R = R3>>
22         where
23             C::R: Mul<R2, Output = R3>,
24         {
25             self.join(other.map(|x| (x, ()))).map(|(k, x, ())| (k, x))
26         }
27     }
28 }
29
30 mod core {
31     mod operator {
32         mod join {
33             use super::Op;
34             use crate::core::Relation;
35             use std::ops::{AddAssign, Mul};
36             struct Join<LC, RC> {
37                 _left: LC,
38                 _right: RC,
39             }
40             impl<
41                     LC: Op<D = (K, LD), R = LR>,
42                     RC: Op<D = (K, RD), R = RR>,
43                     K: 'static,
44                     LD: 'static,
45                     LR: AddAssign<LR> + Mul<RR, Output = OR>,
46                     RD: 'static,
47                     RR: AddAssign<RR>,
48                     OR: AddAssign<OR>,
49                 > Op for Join<LC, RC>
50             {
51                 type D = (K, LD, RD);
52                 type R = OR;
53             }
54             impl<K: 'static, D: 'static, C: Op<D = (K, D)>> Relation<C> {
55                 pub fn join<C2: Op<D = (K, D2)>, D2: 'static, OR: AddAssign<OR>>(
56                     self,
57                     other: Relation<C2>,
58                 ) -> Relation<impl Op<D = (K, D, D2), R = OR>>
59                 where
60                     C::R: Mul<C2::R, Output = OR>,
61                 {
62                     Relation {
63                         inner: Join {
64                             _left: self.inner,
65                             _right: other.inner,
66                         },
67                     }
68                 }
69             }
70         }
71         mod map {
72             use super::Op;
73             use crate::core::Relation;
74             use std::ops::AddAssign;
75             struct Map<C, MF> {
76                 _inner: C,
77                 _op: MF,
78             }
79             impl<
80                     D1,
81                     R1,
82                     D2: 'static,
83                     R2: AddAssign<R2>,
84                     C: Op<D = D1, R = R1>,
85                     MF: Fn(D1, R1) -> (D2, R2),
86                 > Op for Map<C, MF>
87             {
88                 type D = D2;
89                 type R = R2;
90             }
91             impl<C: Op> Relation<C> {
92                 pub fn map_dr<F: Fn(C::D, C::R) -> (D2, R2), D2: 'static, R2: AddAssign<R2>>(
93                     self,
94                     f: F,
95                 ) -> Relation<impl Op<D = D2, R = R2>> {
96                     Relation {
97                         inner: Map {
98                             _inner: self.inner,
99                             _op: f,
100                         },
101                     }
102                 }
103             }
104         }
105         use std::ops::AddAssign;
106         pub trait Op {
107             type D: 'static;
108             type R: AddAssign<Self::R>;
109         }
110     }
111     pub use self::operator::Op;
112     #[derive(Clone)]
113     pub struct Relation<C> {
114         inner: C,
115     }
116 }
117
118 use self::core::Op;
119 pub use self::core::Relation;
120
121 fn main() {}