luaur_analysis/methods/
overload_resolver_test_function_or_call_metamethod.rs1use crate::functions::find_metatable_entry::find_metatable_entry;
9use crate::functions::follow_type::follow_type_id;
10use crate::functions::get_type_alt_j::get_type_id;
11use crate::records::function_type::FunctionType;
12use crate::records::intersection_type::IntersectionType;
13use crate::records::overload_resolution::OverloadResolution;
14use crate::records::overload_resolver::OverloadResolver;
15use crate::type_aliases::error_vec::ErrorVec;
16use crate::type_aliases::type_id::TypeId;
17use crate::type_aliases::type_pack_id::TypePackId;
18use luaur_ast::records::location::Location;
19use luaur_common::records::dense_hash_set::DenseHashSet;
20
21impl OverloadResolver {
22 pub fn test_function_or_call_metamethod(
23 &mut self,
24 result: &mut OverloadResolution,
25 fn_ty: TypeId,
26 args_pack: TypePackId,
27 fn_location: Location,
28 unique_types: *mut DenseHashSet<TypeId>,
29 ) {
30 let mut fn_ty = unsafe { follow_type_id(fn_ty) };
31 let mut args_pack = args_pack;
32
33 let mut dummy_errors: ErrorVec = alloc::vec::Vec::new();
34 if let Some(call_metamethod) = find_metatable_entry(
35 self.builtin_types,
36 &mut dummy_errors,
37 fn_ty,
38 "__call",
39 self.call_loc,
40 ) {
41 args_pack = unsafe {
43 (*self.arena).add_type_pack_vector_type_id_optional_type_pack_id(
44 alloc::vec![fn_ty],
45 Some(args_pack),
46 )
47 };
48 fn_ty = unsafe { follow_type_id(call_metamethod) };
49
50 let it = unsafe { get_type_id::<IntersectionType>(fn_ty) };
52 if !it.is_null() {
53 let it = unsafe { &*it };
54 let parts = it.parts.clone();
55 for component in parts {
56 let component = unsafe { follow_type_id(component) };
57 result.metamethods.insert(component);
58 let fn_ptr = unsafe { get_type_id::<FunctionType>(component) };
59
60 if !fn_ptr.is_null()
61 && !self.is_arity_compatible(
62 args_pack,
63 unsafe { (*fn_ptr).arg_types },
64 self.builtin_types,
65 )
66 {
67 result.arity_mismatches.push(component);
68 } else {
69 self.test_function(result, component, args_pack, fn_location, unique_types);
70 }
71 }
72 return;
73 }
74
75 result.metamethods.insert(fn_ty);
76 }
77
78 self.test_function(result, fn_ty, args_pack, fn_location, unique_types);
80 }
81}