Skip to main content

telltale_language/compiler/projection/
merge_eq.rs

1//! Structural equality for local session types.
2
3use super::*;
4
5impl PartialEq for LocalType {
6    #[allow(clippy::too_many_lines)]
7    fn eq(&self, other: &Self) -> bool {
8        match (self, other) {
9            (LocalType::End, LocalType::End) => true,
10            (LocalType::Var(a), LocalType::Var(b)) => a == b,
11            (
12                LocalType::Send {
13                    to: to1,
14                    message: msg1,
15                    continuation: cont1,
16                },
17                LocalType::Send {
18                    to: to2,
19                    message: msg2,
20                    continuation: cont2,
21                },
22            ) => to1 == to2 && msg1.name == msg2.name && cont1 == cont2,
23            (
24                LocalType::Receive {
25                    from: from1,
26                    message: msg1,
27                    continuation: cont1,
28                },
29                LocalType::Receive {
30                    from: from2,
31                    message: msg2,
32                    continuation: cont2,
33                },
34            ) => from1 == from2 && msg1.name == msg2.name && cont1 == cont2,
35            (
36                LocalType::Select {
37                    to: to1,
38                    branches: br1,
39                },
40                LocalType::Select {
41                    to: to2,
42                    branches: br2,
43                },
44            ) => {
45                to1 == to2
46                    && br1.len() == br2.len()
47                    && br1
48                        .iter()
49                        .zip(br2.iter())
50                        .all(|((l1, t1), (l2, t2))| l1 == l2 && t1 == t2)
51            }
52            (
53                LocalType::Branch {
54                    from: from1,
55                    branches: br1,
56                },
57                LocalType::Branch {
58                    from: from2,
59                    branches: br2,
60                },
61            ) => {
62                from1 == from2
63                    && br1.len() == br2.len()
64                    && br1
65                        .iter()
66                        .zip(br2.iter())
67                        .all(|((l1, t1), (l2, t2))| l1 == l2 && t1 == t2)
68            }
69            (
70                LocalType::LocalChoice { branches: br1 },
71                LocalType::LocalChoice { branches: br2 },
72            ) => {
73                br1.len() == br2.len()
74                    && br1
75                        .iter()
76                        .zip(br2.iter())
77                        .all(|((l1, t1), (l2, t2))| l1 == l2 && t1 == t2)
78            }
79            (
80                LocalType::Loop {
81                    condition: c1,
82                    body: b1,
83                },
84                LocalType::Loop {
85                    condition: c2,
86                    body: b2,
87                },
88            ) => {
89                // For conditions, we compare structurally
90                let cond_eq = match (c1, c2) {
91                    (None, None) => true,
92                    (
93                        Some(crate::ast::protocol::Condition::Count(n1)),
94                        Some(crate::ast::protocol::Condition::Count(n2)),
95                    ) => n1 == n2,
96                    (
97                        Some(crate::ast::protocol::Condition::RoleDecides(r1)),
98                        Some(crate::ast::protocol::Condition::RoleDecides(r2)),
99                    ) => r1 == r2,
100                    _ => false,
101                };
102                cond_eq && b1 == b2
103            }
104            (
105                LocalType::Rec {
106                    label: l1,
107                    body: b1,
108                },
109                LocalType::Rec {
110                    label: l2,
111                    body: b2,
112                },
113            ) => l1 == l2 && b1 == b2,
114            (
115                LocalType::Timeout {
116                    duration: d1,
117                    body: b1,
118                    on_timeout: t1,
119                    on_cancel: c1,
120                },
121                LocalType::Timeout {
122                    duration: d2,
123                    body: b2,
124                    on_timeout: t2,
125                    on_cancel: c2,
126                },
127            ) => d1 == d2 && b1 == b2 && t1 == t2 && c1 == c2,
128            _ => false,
129        }
130    }
131}
132
133impl Eq for LocalType {}