|
@@ -4872,25 +4872,16 @@ bool is_expr_constant_zero(Ast *expr) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
|
|
- ast_node(ce, CallExpr, call);
|
|
|
- GB_ASSERT(is_type_proc(proc_type));
|
|
|
- proc_type = base_type(proc_type);
|
|
|
- TypeProc *pt = &proc_type->Proc;
|
|
|
-
|
|
|
+isize get_procedure_param_count_excluding_defaults(Type *pt, isize *param_count_) {
|
|
|
+ GB_ASSERT(pt != nullptr);
|
|
|
+ GB_ASSERT(pt->kind == Type_Proc);
|
|
|
isize param_count = 0;
|
|
|
isize param_count_excluding_defaults = 0;
|
|
|
- bool variadic = pt->variadic;
|
|
|
- bool vari_expand = (ce->ellipsis.pos.line != 0);
|
|
|
- i64 score = 0;
|
|
|
- bool show_error = show_error_mode == CallArgumentMode_ShowErrors;
|
|
|
-
|
|
|
-
|
|
|
+ bool variadic = pt->Proc.variadic;
|
|
|
TypeTuple *param_tuple = nullptr;
|
|
|
|
|
|
- if (pt->params != nullptr) {
|
|
|
- param_tuple = &pt->params->Tuple;
|
|
|
+ if (pt->Proc.params != nullptr) {
|
|
|
+ param_tuple = &pt->Proc.params->Tuple;
|
|
|
|
|
|
param_count = param_tuple->variables.count;
|
|
|
if (variadic) {
|
|
@@ -4930,6 +4921,31 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (param_count_) *param_count_ = param_count;
|
|
|
+ return param_count_excluding_defaults;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
|
|
+ ast_node(ce, CallExpr, call);
|
|
|
+ GB_ASSERT(is_type_proc(proc_type));
|
|
|
+ proc_type = base_type(proc_type);
|
|
|
+ TypeProc *pt = &proc_type->Proc;
|
|
|
+
|
|
|
+ isize param_count = 0;
|
|
|
+ isize param_count_excluding_defaults = get_procedure_param_count_excluding_defaults(proc_type, ¶m_count);
|
|
|
+ bool variadic = pt->variadic;
|
|
|
+ bool vari_expand = (ce->ellipsis.pos.line != 0);
|
|
|
+ i64 score = 0;
|
|
|
+ bool show_error = show_error_mode == CallArgumentMode_ShowErrors;
|
|
|
+
|
|
|
+
|
|
|
+ TypeTuple *param_tuple = nullptr;
|
|
|
+ if (pt->params != nullptr) {
|
|
|
+ param_tuple = &pt->params->Tuple;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
CallArgumentError err = CallArgumentError_None;
|
|
|
Type *final_proc_type = proc_type;
|
|
|
Entity *gen_entity = nullptr;
|
|
@@ -5602,7 +5618,37 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|
|
if (operand->mode == Addressing_ProcGroup) {
|
|
|
check_entity_decl(c, operand->proc_group, nullptr, nullptr);
|
|
|
|
|
|
- Array<Entity *> procs = proc_group_entities(c, *operand);
|
|
|
+ auto procs = proc_group_entities_cloned(c, *operand);
|
|
|
+
|
|
|
+ if (procs.count > 1) {
|
|
|
+ isize max_arg_count = args.count;
|
|
|
+ for_array(i, args) {
|
|
|
+ // NOTE(bill): The only thing that may have multiple values
|
|
|
+ // will be a call expression (assuming `or_return` and `()` will be stripped)
|
|
|
+ Ast *arg = strip_or_return_expr(args[i]);
|
|
|
+ if (arg && arg->kind == Ast_CallExpr) {
|
|
|
+ max_arg_count = ISIZE_MAX;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (isize proc_index = 0; proc_index < procs.count; /**/) {
|
|
|
+ Entity *proc = procs[proc_index];
|
|
|
+ Type *pt = base_type(proc->type);
|
|
|
+ if (!(pt != nullptr && is_type_proc(pt))) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ isize param_count = 0;
|
|
|
+ isize param_count_excluding_defaults = get_procedure_param_count_excluding_defaults(pt, ¶m_count);
|
|
|
+
|
|
|
+ if (param_count_excluding_defaults > max_arg_count) {
|
|
|
+ array_unordered_remove(&procs, proc_index);
|
|
|
+ } else {
|
|
|
+ proc_index++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if (procs.count == 1) {
|
|
|
Ast *ident = operand->expr;
|
|
@@ -5632,6 +5678,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|
|
return data;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
Entity **lhs = nullptr;
|
|
|
isize lhs_count = -1;
|
|
|
|