luaur_analysis/methods/
unifier_try_apply_overloaded_function.rs1use crate::functions::get_type_alt_j::get_type_id;
3use crate::functions::has_unification_too_complex::has_unification_too_complex;
4use crate::records::cannot_call_non_function::CannotCallNonFunction;
5use crate::records::function_type::FunctionType;
6use crate::records::generic_error::GenericError;
7use crate::records::normalized_function_type::NormalizedFunctionType;
8use crate::records::unifier::Unifier;
9use crate::type_aliases::type_error_data::TypeErrorData;
10use crate::type_aliases::type_id::TypeId;
11use crate::type_aliases::type_pack_id::TypePackId;
12use alloc::string::String;
13
14impl Unifier {
15 pub fn unifier_try_apply_overloaded_function(
17 &mut self,
18 function: TypeId,
19 overloads: &NormalizedFunctionType,
20 args: TypePackId,
21 ) -> TypePackId {
22 if overloads.is_never() {
23 self.report_error_location_type_error_data(
24 self.location,
25 TypeErrorData::CannotCallNonFunction(CannotCallNonFunction { ty: function }),
26 );
27 return unsafe { (*self.builtin_types).errorTypePack };
28 }
29
30 let mut result: Option<TypePackId> = None;
31 let mut first_fun: *const FunctionType = core::ptr::null();
32
33 let parts = overloads.parts.order.clone();
34 for overload in parts {
35 let ftv = unsafe { get_type_id::<FunctionType>(overload) };
36 if !ftv.is_null() {
37 if unsafe { (*ftv).generics.is_empty() && (*ftv).generic_packs.is_empty() } {
39 if first_fun.is_null() {
40 first_fun = ftv;
41 }
42 let mut inner_state = self.unifier_make_child_unifier();
43 inner_state.try_unify_type_pack_id_type_pack_id_bool(
44 args,
45 unsafe { (*ftv).arg_types },
46 false,
47 );
48 if inner_state.errors.is_empty() {
49 self.log.concat(inner_state.log.clone());
50 if let Some(res) = result {
51 inner_state.log.clear();
52 inner_state.try_unify_type_pack_id_type_pack_id_bool(
53 res,
54 unsafe { (*ftv).ret_types },
55 false,
56 );
57 if inner_state.errors.is_empty() {
58 self.log.concat(inner_state.log.clone());
59 }
60 else if let Some(intersect) = unsafe {
64 (*self.normalizer).intersection_of_type_packs(res, (*ftv).ret_types)
65 } {
66 result = Some(intersect);
67 }
68 } else {
69 result = Some(unsafe { (*ftv).ret_types });
70 }
71 } else if let Some(e) = has_unification_too_complex(&inner_state.errors) {
72 self.report_error_type_error(e);
73 return unsafe { (*self.builtin_types).error_recovery_type_pack(args) };
74 }
75 }
76 }
77 }
78
79 if let Some(res) = result {
80 res
81 } else if !first_fun.is_null() {
82 self.report_error_location_type_error_data(
86 self.location,
87 TypeErrorData::GenericError(GenericError::new(String::from(
88 "No matching overload.",
89 ))),
90 );
91 unsafe { (*self.builtin_types).error_recovery_type_pack((*first_fun).ret_types) }
92 } else {
93 self.report_error_location_type_error_data(
94 self.location,
95 TypeErrorData::CannotCallNonFunction(CannotCallNonFunction { ty: function }),
96 );
97 unsafe { (*self.builtin_types).errorTypePack }
98 }
99 }
100}