luaur_analysis/methods/
unifier_reflexive_equal.rs1use crate::records::function_type::FunctionType;
17use crate::records::intersection_type::IntersectionType;
18use crate::records::type_pack::TypePack;
19use crate::records::unifier::Unifier;
20use crate::records::union_type::UnionType;
21use crate::type_aliases::type_id::TypeId;
22use crate::type_aliases::type_pack_id::TypePackId;
23
24impl Unifier {
25 pub(crate) fn reflexive_equal_type_id(&self, a: TypeId, b: TypeId, depth: u32) -> bool {
26 if depth == 0 {
27 return false;
28 }
29 let a = self.log.follow_type_id(a);
30 let b = self.log.follow_type_id(b);
31 if a == b {
32 return true;
33 }
34 unsafe {
35 let au = self.log.txn_log_get::<UnionType, TypeId>(a);
36 let bu = self.log.txn_log_get::<UnionType, TypeId>(b);
37 if !au.is_null() && !bu.is_null() {
38 let ao = &(*au).options;
39 let bo = &(*bu).options;
40 return ao.len() == bo.len()
41 && ao
42 .iter()
43 .zip(bo.iter())
44 .all(|(x, y)| self.reflexive_equal_type_id(*x, *y, depth - 1));
45 }
46
47 let ai = self.log.txn_log_get::<IntersectionType, TypeId>(a);
48 let bi = self.log.txn_log_get::<IntersectionType, TypeId>(b);
49 if !ai.is_null() && !bi.is_null() {
50 let ap = &(*ai).parts;
51 let bp = &(*bi).parts;
52 return ap.len() == bp.len()
53 && ap
54 .iter()
55 .zip(bp.iter())
56 .all(|(x, y)| self.reflexive_equal_type_id(*x, *y, depth - 1));
57 }
58
59 let af = self.log.txn_log_get::<FunctionType, TypeId>(a);
60 let bf = self.log.txn_log_get::<FunctionType, TypeId>(b);
61 if !af.is_null() && !bf.is_null() {
62 return self.reflexive_equal_type_pack_id(
63 (*af).arg_types,
64 (*bf).arg_types,
65 depth - 1,
66 ) && self.reflexive_equal_type_pack_id(
67 (*af).ret_types,
68 (*bf).ret_types,
69 depth - 1,
70 );
71 }
72 }
73 false
74 }
75
76 pub(crate) fn reflexive_equal_type_pack_id(
77 &self,
78 a: TypePackId,
79 b: TypePackId,
80 depth: u32,
81 ) -> bool {
82 if depth == 0 {
83 return false;
84 }
85 let a = self.log.follow_type_pack_id(a);
86 let b = self.log.follow_type_pack_id(b);
87 if a == b {
88 return true;
89 }
90 unsafe {
91 let ap = self.log.txn_log_get::<TypePack, TypePackId>(a);
92 let bp = self.log.txn_log_get::<TypePack, TypePackId>(b);
93 if !ap.is_null() && !bp.is_null() {
94 let ah = &(*ap).head;
95 let bh = &(*bp).head;
96 if ah.len() != bh.len() {
97 return false;
98 }
99 if !ah
100 .iter()
101 .zip(bh.iter())
102 .all(|(x, y)| self.reflexive_equal_type_id(*x, *y, depth - 1))
103 {
104 return false;
105 }
106 return match (&(*ap).tail, &(*bp).tail) {
107 (None, None) => true,
108 (Some(ta), Some(tb)) => self.reflexive_equal_type_pack_id(*ta, *tb, depth - 1),
109 _ => false,
110 };
111 }
112 }
113 false
114 }
115}