Skip to main content

luaur_analysis/methods/
unifier_occurs_check_unifier_alt_d.rs

1use crate::functions::get_type_pack::get_type_pack_id;
2use crate::records::free_type_pack::FreeTypePack;
3use crate::records::type_pack::TypePack;
4use crate::records::unifier::Unifier;
5use crate::type_aliases::error_type_pack::ErrorTypePack;
6use crate::type_aliases::type_pack_id::TypePackId;
7use luaur_common::records::dense_hash_set::DenseHashSet;
8
9impl Unifier {
10    pub fn occurs_check_dense_hash_set_type_pack_id_type_pack_id_type_pack_id(
11        &mut self,
12        seen: &mut DenseHashSet<TypePackId>,
13        mut needle: TypePackId,
14        mut haystack: TypePackId,
15    ) -> bool {
16        needle = self.log.follow_type_pack_id(needle);
17        haystack = self.log.follow_type_pack_id(haystack);
18
19        if seen.find(&haystack).is_some() {
20            return false;
21        }
22
23        seen.insert(haystack);
24
25        if !unsafe { get_type_pack_id::<ErrorTypePack>(needle) }.is_null() {
26            return false;
27        }
28
29        if unsafe { get_type_pack_id::<FreeTypePack>(needle) }.is_null() {
30            self.ice_string("Expected needle pack to be free");
31        }
32
33        while unsafe { get_type_pack_id::<ErrorTypePack>(haystack) }.is_null() {
34            if needle == haystack {
35                return true;
36            }
37
38            let pack = unsafe { get_type_pack_id::<TypePack>(haystack) };
39            if !pack.is_null() {
40                if let Some(tail) = unsafe { (*pack).tail } {
41                    haystack = self.log.follow_type_pack_id(tail);
42                    continue;
43                }
44            }
45
46            break;
47        }
48
49        false
50    }
51}