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