luaur_analysis/methods/
unifier_try_unify_variadics.rs1use crate::functions::begin_type_pack_alt_d::begin;
3use crate::functions::end_type_pack::end;
4use crate::functions::follow_type::follow as follow_type;
5use crate::functions::follow_type_pack::follow as follow_pack;
6use crate::functions::get_type_pack::get_type_pack_id;
7use crate::functions::is_blocked_unifier_alt_c::is_blocked_txn_log_type_pack_id;
8use crate::records::any_type::AnyType;
9use crate::records::free_type_pack::FreeTypePack;
10use crate::records::generic_error::GenericError;
11use crate::records::generic_type_pack::GenericTypePack;
12use crate::records::type_pack::TypePack;
13use crate::records::type_pack_var::TypePackVar;
14use crate::records::unifier::Unifier;
15use crate::records::variadic_type_pack::VariadicTypePack;
16use crate::type_aliases::error_type_pack::ErrorTypePack;
17use crate::type_aliases::type_error_data::TypeErrorData;
18use crate::type_aliases::type_pack_id::TypePackId;
19use crate::type_aliases::type_pack_variant::TypePackVariant;
20use alloc::string::String;
21
22impl Unifier {
23 pub fn unifier_try_unify_variadics(
25 &mut self,
26 sub_tp: TypePackId,
27 super_tp: TypePackId,
28 reversed: bool,
29 sub_offset: i32,
30 ) {
31 let super_variadic = self
32 .log
33 .txn_log_get_mutable::<VariadicTypePack, TypePackId>(super_tp);
34 let variadic_ty = unsafe { follow_type((*super_variadic).ty) };
35
36 if super_variadic.is_null() {
37 self.ice_string("passed non-variadic pack to tryUnifyVariadics");
38 }
39
40 let sub_variadic = self.log.txn_log_get::<VariadicTypePack, TypePackId>(sub_tp);
41 if !sub_variadic.is_null() {
42 let (a, b) = if reversed {
43 (variadic_ty, unsafe { (*sub_variadic).ty })
44 } else {
45 (unsafe { (*sub_variadic).ty }, variadic_ty)
46 };
47 self.try_unify_type_id_type_id_bool_bool_literal_properties(a, b, false, false, None);
48 } else if !self
49 .log
50 .txn_log_get::<TypePack, TypePackId>(sub_tp)
51 .is_null()
52 {
53 let mut sub_iter = begin(sub_tp, &self.log as *const _);
54 let sub_end = end(sub_tp);
55
56 for _ in 0..sub_offset {
57 sub_iter.operator_inc();
58 }
59
60 while sub_iter.operator_ne(&sub_end) {
61 let cur = *sub_iter.operator_deref();
62 let (a, b) = if reversed {
63 (variadic_ty, cur)
64 } else {
65 (cur, variadic_ty)
66 };
67 self.try_unify_type_id_type_id_bool_bool_literal_properties(
68 a, b, false, false, None,
69 );
70 sub_iter.operator_inc();
71 }
72
73 if let Some(maybe_tail) = sub_iter.tail() {
74 let tail = unsafe { follow_pack(maybe_tail) };
75
76 if is_blocked_txn_log_type_pack_id(&self.log, tail) {
77 self.blocked_type_packs.push(tail);
78 } else if !unsafe { get_type_pack_id::<FreeTypePack>(tail) }.is_null() {
79 let bound = TypePackVar {
81 ty: TypePackVariant::Bound(super_tp),
82 persistent: false,
83 owningArena: core::ptr::null_mut(),
84 };
85 self.log.replace_type_pack_id_type_pack_var(tail, bound);
86 } else if let Some(vtp) =
87 unsafe { get_type_pack_id::<VariadicTypePack>(tail).as_ref() }
88 {
89 self.try_unify_type_id_type_id_bool_bool_literal_properties(
90 vtp.ty,
91 variadic_ty,
92 false,
93 false,
94 None,
95 );
96 } else if !unsafe { get_type_pack_id::<GenericTypePack>(tail) }.is_null() {
97 self.report_error_location_type_error_data(
98 self.location,
99 TypeErrorData::GenericError(GenericError::new(String::from(
100 "Cannot unify variadic and generic packs",
101 ))),
102 );
103 } else if !unsafe { get_type_pack_id::<ErrorTypePack>(tail) }.is_null() {
104 } else {
106 self.ice_string("Unknown TypePack kind");
107 }
108 }
109 } else if !unsafe { crate::functions::get_type_alt_j::get_type_id::<AnyType>(variadic_ty) }
110 .is_null()
111 && !self
112 .log
113 .txn_log_get::<GenericTypePack, TypePackId>(sub_tp)
114 .is_null()
115 {
116 } else {
118 self.report_error_location_type_error_data(
119 self.location,
120 TypeErrorData::GenericError(GenericError::new(String::from(
121 "Failed to unify variadic packs",
122 ))),
123 );
124 }
125 }
126}