luaur_analysis/methods/
overload_resolver_test_function_or_union.rs1use crate::functions::follow_type::follow_type_id;
3use crate::functions::get_type_alt_j::get_type_id;
4use crate::records::cannot_call_non_function::CannotCallNonFunction;
5use crate::records::overload_resolution::OverloadResolution;
6use crate::records::overload_resolver::OverloadResolver;
7use crate::records::type_error::TypeError;
8use crate::records::union_type::UnionType;
9use crate::type_aliases::type_error_data::TypeErrorData;
10use crate::type_aliases::type_id::TypeId;
11use crate::type_aliases::type_pack_id::TypePackId;
12use luaur_ast::records::location::Location;
13use luaur_common::macros::luau_assert::LUAU_ASSERT;
14use luaur_common::records::dense_hash_set::DenseHashSet;
15use luaur_common::records::variant::Variant2;
16
17impl OverloadResolver {
18 pub fn test_function_or_union(
19 &mut self,
20 result: &mut OverloadResolution,
21 fn_ty: TypeId,
22 args_pack: TypePackId,
23 fn_location: Location,
24 unique_types: *mut DenseHashSet<TypeId>,
25 ) {
26 let fn_ty = unsafe { follow_type_id(fn_ty) };
27 LUAU_ASSERT!(fn_ty == unsafe { follow_type_id(fn_ty) });
28
29 let ut = unsafe { get_type_id::<UnionType>(fn_ty) };
30 if !ut.is_null() {
31 let mut inner_result = OverloadResolution {
34 ok: alloc::vec::Vec::new(),
35 non_functions: alloc::vec::Vec::new(),
36 potential_overloads: alloc::vec::Vec::new(),
37 incompatible_overloads: alloc::vec::Vec::new(),
38 arity_mismatches: alloc::vec::Vec::new(),
39 metamethods: DenseHashSet::new(core::ptr::null_mut()),
40 };
41 let options = unsafe { (*ut).options.clone() };
42 let mut count: usize = 0;
43 for t in options {
44 count += 1;
45 self.test_function_or_call_metamethod(
46 &mut inner_result,
47 t,
48 args_pack,
49 fn_location,
50 unique_types,
51 );
52 }
53
54 if count == inner_result.ok.len() {
55 result.ok.push(fn_ty);
56 } else if count == inner_result.ok.len() + inner_result.potential_overloads.len() {
57 let mut all_constraints = alloc::vec::Vec::new();
58 for (_t, constraints) in inner_result.potential_overloads.iter() {
59 all_constraints.extend(constraints.iter().cloned());
60 }
61
62 result.potential_overloads.push((fn_ty, all_constraints));
63 } else {
64 let errors = alloc::vec![TypeError::type_error_location_type_error_data(
67 fn_location,
68 TypeErrorData::CannotCallNonFunction(CannotCallNonFunction { ty: fn_ty }),
69 )];
70 result
71 .incompatible_overloads
72 .push((fn_ty, Variant2::V1(errors)));
73 }
74 } else {
75 self.test_function_or_call_metamethod(
76 result,
77 fn_ty,
78 args_pack,
79 fn_location,
80 unique_types,
81 );
82 }
83 }
84}