Skip to main content

luaur_analysis/methods/
unifier_2_occurs_check_deprecated.rs

1//! Source: `Analysis/src/Unifier2.cpp:873-906` —
2//! `Unifier2::occursCheck_DEPRECATED(DenseHashSet<TypePackId>&, TypePackId, TypePackId)`.
3
4use crate::enums::occurs_check_result::OccursCheckResult;
5use crate::functions::follow_type_pack::follow_type_pack_id;
6use crate::functions::get_mutable_type_pack::get_mutable_type_pack_id;
7use crate::functions::get_type_pack::get_type_pack_id;
8use crate::records::free_type_pack::FreeTypePack;
9use crate::records::recursion_limiter::RecursionLimiter;
10use crate::records::type_pack::TypePack;
11use crate::records::unifier_2::Unifier2;
12use crate::type_aliases::error_type_pack::ErrorTypePack;
13use crate::type_aliases::type_pack_id::TypePackId;
14use luaur_common::records::dense_hash_set::DenseHashSet;
15
16impl Unifier2 {
17    pub fn occurs_check_deprecated(
18        &mut self,
19        seen: &mut DenseHashSet<TypePackId>,
20        needle: TypePackId,
21        mut haystack: TypePackId,
22    ) -> OccursCheckResult {
23        let needle = unsafe { follow_type_pack_id(needle) };
24        haystack = unsafe { follow_type_pack_id(haystack) };
25
26        if seen.find(&haystack).is_some() {
27            return OccursCheckResult::Pass;
28        }
29
30        seen.insert(haystack);
31
32        if !unsafe { get_mutable_type_pack_id::<ErrorTypePack>(needle) }.is_null() {
33            return OccursCheckResult::Pass;
34        }
35
36        if unsafe { get_mutable_type_pack_id::<FreeTypePack>(needle) }.is_null() {
37            unsafe { (*self.ice.as_ptr()).ice_string("Expected needle pack to be free") };
38        }
39
40        let mut _ra = RecursionLimiter {
41            base: unsafe { core::mem::zeroed() },
42            native_stack_guard: unsafe { core::mem::zeroed() },
43        };
44        _ra.recursion_limiter_recursion_limiter(
45            "Unifier2::occursCheck",
46            &mut self.recursion_count as *mut i32 as *mut core::ffi::c_int,
47            self.recursion_limit as core::ffi::c_int,
48        );
49
50        while unsafe { get_mutable_type_pack_id::<ErrorTypePack>(haystack) }.is_null() {
51            if needle == haystack {
52                return OccursCheckResult::Fail;
53            }
54
55            let a = unsafe { get_type_pack_id::<TypePack>(haystack) };
56            if !a.is_null() {
57                if let Some(tail) = unsafe { (*a).tail } {
58                    haystack = unsafe { follow_type_pack_id(tail) };
59                    continue;
60                }
61            }
62
63            break;
64        }
65
66        OccursCheckResult::Pass
67    }
68}