luaur_analysis/methods/
normalizer_intersection_of_functions.rs1use crate::records::function_type::FunctionType;
2use crate::records::normalizer::Normalizer;
3use crate::type_aliases::type_id::TypeId;
4use crate::type_aliases::type_pack_id::TypePackId;
5use luaur_common::macros::luau_assert::LUAU_ASSERT;
6
7impl Normalizer {
8 pub fn intersection_of_functions(&mut self, here: TypeId, there: TypeId) -> Option<TypeId> {
9 self.consume_fuel();
10
11 let hftv: *const FunctionType =
12 unsafe { crate::functions::get_type_alt_j::get_type_id::<FunctionType>(here) };
13 if hftv.is_null() {
14 return None;
15 }
16 let tftv: *const FunctionType =
17 unsafe { crate::functions::get_type_alt_j::get_type_id::<FunctionType>(there) };
18 if tftv.is_null() {
19 return None;
20 }
21
22 let hftv_ref = unsafe { &*hftv };
23 let tftv_ref = unsafe { &*tftv };
24
25 if hftv_ref.generics != tftv_ref.generics {
26 return None;
27 }
28 if hftv_ref.generic_packs != tftv_ref.generic_packs {
29 return None;
30 }
31
32 let mut arg_types: TypePackId = unsafe { core::ptr::null() };
33 let mut ret_types: TypePackId = unsafe { core::ptr::null() };
34
35 if hftv_ref.ret_types == tftv_ref.ret_types {
36 let arg_types_opt = self.union_of_type_packs(hftv_ref.arg_types, tftv_ref.arg_types);
37 if arg_types_opt.is_none() {
38 return None;
39 }
40 arg_types = arg_types_opt.unwrap();
41 ret_types = hftv_ref.ret_types;
42 } else if hftv_ref.arg_types == tftv_ref.arg_types {
43 let ret_types_opt =
44 self.intersection_of_type_packs_internal(hftv_ref.arg_types, tftv_ref.arg_types);
45 if ret_types_opt.is_none() {
46 return None;
47 }
48 arg_types = hftv_ref.arg_types;
49 ret_types = ret_types_opt.unwrap();
50 } else {
51 return None;
52 }
53
54 if arg_types == hftv_ref.arg_types && ret_types == hftv_ref.ret_types {
55 return Some(here);
56 }
57 if arg_types == tftv_ref.arg_types && ret_types == tftv_ref.ret_types {
58 return Some(there);
59 }
60
61 let mut result = FunctionType::function_type_new(arg_types, ret_types, None, false);
62 result.generics = hftv_ref.generics.clone();
63 result.generic_packs = hftv_ref.generic_packs.clone();
64
65 Some(unsafe { (*self.arena).add_type(result) })
66 }
67}