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