Skip to main content

luaur_analysis/methods/
unifier_occurs_check_unifier_alt_b.rs

1//! Source: `Analysis/src/Unifier.cpp` (Unifier::occursCheck(DenseHashSet<TypeId>&,...), L2644-2687)
2use 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    /// `bool Unifier::occursCheck(DenseHashSet<TypeId>& seen, TypeId needle, TypeId haystack)`
13    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}