luaur_analysis/functions/
relate_simplify.rs1use crate::enums::relation::Relation;
2use crate::functions::flip::flip;
3use crate::functions::follow_type::follow_type_id;
4use crate::functions::get_type_alt_j::get_type_id;
5use crate::functions::is_subclass_normalize::is_subclass_type_id_type_id;
6use crate::functions::is_type_variable::is_type_variable;
7use crate::functions::relate_table_to_extern_type::relate_table_to_extern_type;
8use crate::functions::relate_tables::relate_tables;
9use crate::records::any_type::AnyType;
10use crate::records::boolean_singleton::BooleanSingleton;
11use crate::records::extern_type::ExternType;
12use crate::records::function_type::FunctionType;
13use crate::records::intersection_type::IntersectionType;
14use crate::records::metatable_type::MetatableType;
15use crate::records::negation_type::NegationType;
16use crate::records::never_type::NeverType;
17use crate::records::primitive_type::PrimitiveType;
18use crate::records::singleton_type::SingletonType;
19use crate::records::string_singleton::StringSingleton;
20use crate::records::table_type::TableType;
21use crate::records::type_function_instance_type::TypeFunctionInstanceType;
22use crate::records::union_type::UnionType;
23use crate::records::unknown_type::UnknownType;
24use crate::type_aliases::error_type::ErrorType;
25use crate::type_aliases::simplifier_seen_set::SimplifierSeenSet;
26use crate::type_aliases::type_id::TypeId;
27
28pub fn relate(left: TypeId, right: TypeId, seen: &mut SimplifierSeenSet) -> Relation {
30 let left = unsafe { follow_type_id(left) };
33 let right = unsafe { follow_type_id(right) };
34
35 if left == right {
36 return Relation::Coincident;
37 }
38
39 let type_pair = (left, right);
40 if !seen.try_insert(type_pair, true).1 {
41 return Relation::Coincident;
44 }
45
46 unsafe {
47 if !get_type_id::<UnknownType>(left).is_null() {
48 if !get_type_id::<AnyType>(right).is_null() {
49 return Relation::Subset;
50 }
51
52 if !get_type_id::<UnknownType>(right).is_null() {
53 return Relation::Coincident;
54 }
55
56 if !get_type_id::<ErrorType>(right).is_null() {
57 return Relation::Disjoint;
58 }
59
60 return Relation::Superset;
61 }
62
63 if !get_type_id::<UnknownType>(right).is_null() {
64 return flip(relate(right, left, seen));
65 }
66
67 if !get_type_id::<AnyType>(left).is_null() {
68 if !get_type_id::<AnyType>(right).is_null() {
69 return Relation::Coincident;
70 }
71
72 return Relation::Superset;
73 }
74
75 if !get_type_id::<AnyType>(right).is_null() {
76 return flip(relate(right, left, seen));
77 }
78
79 if is_type_variable(left) || is_type_variable(right) {
103 return Relation::Intersects;
104 }
105
106 if !get_type_id::<TypeFunctionInstanceType>(left).is_null()
108 || !get_type_id::<TypeFunctionInstanceType>(right).is_null()
109 {
110 return Relation::Intersects;
111 }
112
113 if !get_type_id::<ErrorType>(left).is_null() {
114 if !get_type_id::<ErrorType>(right).is_null() {
115 return Relation::Coincident;
116 } else if !get_type_id::<AnyType>(right).is_null() {
117 return Relation::Subset;
118 }
119
120 return Relation::Disjoint;
121 } else if !get_type_id::<ErrorType>(right).is_null() {
122 return flip(relate(right, left, seen));
123 }
124
125 if !get_type_id::<NeverType>(left).is_null() {
126 if !get_type_id::<NeverType>(right).is_null() {
127 return Relation::Coincident;
128 }
129
130 return Relation::Subset;
131 } else if !get_type_id::<NeverType>(right).is_null() {
132 return flip(relate(right, left, seen));
133 }
134
135 if !get_type_id::<IntersectionType>(left).is_null() {
136 return Relation::Intersects;
137 } else if !get_type_id::<IntersectionType>(right).is_null() {
138 return Relation::Intersects;
139 }
140
141 if let Some(ut) = get_type_id::<UnionType>(left).as_ref() {
142 for &part in &ut.options {
143 let r = relate(part, right, seen);
144 if r == Relation::Superset || r == Relation::Coincident {
145 return Relation::Superset;
146 }
147 }
148 return Relation::Intersects;
149 } else if let Some(ut) = get_type_id::<UnionType>(right).as_ref() {
150 for &part in &ut.options {
151 let r = relate(left, part, seen);
152 if r == Relation::Subset || r == Relation::Coincident {
153 return Relation::Subset;
154 }
155 }
156 return Relation::Intersects;
157 }
158
159 if let Some(rnt) = get_type_id::<NegationType>(right).as_ref() {
160 let a = relate(left, rnt.ty, seen);
161 match a {
162 Relation::Coincident => {
163 return Relation::Disjoint;
165 }
166 Relation::Disjoint => {
167 if !get_type_id::<NegationType>(left).is_null() {
168 return Relation::Intersects;
170 } else {
171 return Relation::Subset;
173 }
174 }
175 Relation::Intersects => {
176 return Relation::Intersects;
178 }
179 Relation::Subset => {
180 return Relation::Disjoint;
182 }
183 Relation::Superset => {
184 return Relation::Intersects;
188 }
189 }
190 } else if !get_type_id::<NegationType>(left).is_null() {
191 return flip(relate(right, left, seen));
192 }
193
194 if let Some(lp) = get_type_id::<PrimitiveType>(left).as_ref() {
195 if let Some(rp) = get_type_id::<PrimitiveType>(right).as_ref() {
196 if lp.r#type == rp.r#type {
197 return Relation::Coincident;
198 }
199
200 return Relation::Disjoint;
201 }
202
203 if let Some(rs) = get_type_id::<SingletonType>(right).as_ref() {
204 if lp.r#type == PrimitiveType::String
205 && rs.variant.get_if::<StringSingleton>().is_some()
206 {
207 return Relation::Superset;
208 }
209
210 if lp.r#type == PrimitiveType::Boolean
211 && rs.variant.get_if::<BooleanSingleton>().is_some()
212 {
213 return Relation::Superset;
214 }
215
216 return Relation::Disjoint;
217 }
218
219 if lp.r#type == PrimitiveType::Function {
220 if !get_type_id::<FunctionType>(right).is_null() {
221 return Relation::Superset;
222 }
223
224 return Relation::Disjoint;
225 }
226 if lp.r#type == PrimitiveType::Table {
227 if !get_type_id::<TableType>(right).is_null() {
228 return Relation::Superset;
229 }
230
231 return Relation::Disjoint;
232 }
233
234 if !get_type_id::<FunctionType>(right).is_null()
235 || !get_type_id::<TableType>(right).is_null()
236 || !get_type_id::<MetatableType>(right).is_null()
237 || !get_type_id::<ExternType>(right).is_null()
238 {
239 return Relation::Disjoint;
240 }
241 }
242
243 if let Some(ls) = get_type_id::<SingletonType>(left).as_ref() {
244 if !get_type_id::<FunctionType>(right).is_null()
245 || !get_type_id::<TableType>(right).is_null()
246 || !get_type_id::<MetatableType>(right).is_null()
247 || !get_type_id::<ExternType>(right).is_null()
248 {
249 return Relation::Disjoint;
250 }
251
252 if !get_type_id::<PrimitiveType>(right).is_null() {
253 return flip(relate(right, left, seen));
254 }
255
256 if let Some(rs) = get_type_id::<SingletonType>(right).as_ref() {
257 if ls.variant == rs.variant {
258 return Relation::Coincident;
259 }
260
261 return Relation::Disjoint;
262 }
263 }
264
265 if !get_type_id::<FunctionType>(left).is_null() {
266 if let Some(rp) = get_type_id::<PrimitiveType>(right).as_ref() {
267 if rp.r#type == PrimitiveType::Function {
268 return Relation::Subset;
269 }
270
271 return Relation::Disjoint;
272 }
273
274 return Relation::Intersects;
275 }
276
277 if let Some(lt) = get_type_id::<TableType>(left).as_ref() {
278 if let Some(rp) = get_type_id::<PrimitiveType>(right).as_ref() {
279 if rp.r#type == PrimitiveType::Table {
280 return Relation::Subset;
281 }
282
283 return Relation::Disjoint;
284 }
285
286 if let Some(rt) = get_type_id::<TableType>(right).as_ref() {
287 return relate_tables(lt, rt, seen);
288 }
289
290 if let Some(re) = get_type_id::<ExternType>(right).as_ref() {
291 return relate_table_to_extern_type(lt, re, seen);
292 }
293
294 return Relation::Disjoint;
297 }
298
299 if let Some(ct) = get_type_id::<ExternType>(left).as_ref() {
300 if get_type_id::<ExternType>(right).as_ref().is_some() {
301 if is_subclass_type_id_type_id(left, right) {
302 return Relation::Subset;
303 }
304
305 if is_subclass_type_id_type_id(right, left) {
306 return Relation::Superset;
307 }
308
309 return Relation::Disjoint;
310 }
311
312 if let Some(tbl) = get_type_id::<TableType>(right).as_ref() {
313 return flip(relate_table_to_extern_type(tbl, ct, seen));
314 }
315
316 return Relation::Disjoint;
317 }
318 }
319
320 Relation::Intersects
321}