luaur_analysis/methods/
unifier_2_occurs_check_deprecated.rs1use 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}