luaur_analysis/methods/
unifier_occurs_check_unifier_alt_b.rs1use crate::functions::get_mutable_type::get_mutable_type_id;
3use crate::records::free_type::FreeType;
4use crate::records::intersection_type::IntersectionType;
5use crate::records::unifier::Unifier;
6use crate::records::union_type::UnionType;
7use crate::type_aliases::error_type::ErrorType;
8use crate::type_aliases::type_id::TypeId;
9use luaur_common::records::dense_hash_set::DenseHashSet;
10
11impl Unifier {
12 pub fn occurs_check_dense_hash_set_type_id_type_id_type_id(
14 &mut self,
15 seen: &mut DenseHashSet<TypeId>,
16 mut needle: TypeId,
17 mut haystack: TypeId,
18 ) -> bool {
19 let mut occurrence = false;
20
21 needle = self.log.follow_type_id(needle);
22 haystack = self.log.follow_type_id(haystack);
23
24 if seen.find(&haystack).is_some() {
25 return false;
26 }
27
28 seen.insert(haystack);
29
30 if !unsafe { get_mutable_type_id::<ErrorType>(needle) }.is_null() {
31 return false;
32 }
33
34 if unsafe { get_mutable_type_id::<FreeType>(needle) }.is_null() {
35 self.ice_string("Expected needle to be free");
36 }
37
38 if needle == haystack {
39 return true;
40 }
41
42 if !unsafe { get_mutable_type_id::<FreeType>(haystack) }.is_null() {
43 return false;
44 } else if let Some(a) = unsafe { get_mutable_type_id::<UnionType>(haystack).as_ref() } {
45 let options = a.options.clone();
46 for ty in options {
47 if self.occurs_check_dense_hash_set_type_id_type_id_type_id(seen, needle, ty) {
48 occurrence = true;
49 }
50 }
51 } else if let Some(a) =
52 unsafe { get_mutable_type_id::<IntersectionType>(haystack).as_ref() }
53 {
54 let parts = a.parts.clone();
55 for ty in parts {
56 if self.occurs_check_dense_hash_set_type_id_type_id_type_id(seen, needle, ty) {
57 occurrence = true;
58 }
59 }
60 }
61
62 occurrence
63 }
64}