diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e0c6be1d1..eb3713d82 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5314,7 +5314,7 @@ gb_internal isize get_procedure_param_count_excluding_defaults(Type *pt, isize * } -gb_internal isize lookup_procedure_parameter(TypeProc *pt, String parameter_name) { +gb_internal isize lookup_procedure_parameter(TypeProc *pt, String const ¶meter_name) { isize param_count = pt->param_count; for (isize i = 0; i < param_count; i++) { Entity *e = pt->params->Tuple.variables[i]; @@ -5329,6 +5329,13 @@ gb_internal isize lookup_procedure_parameter(TypeProc *pt, String parameter_name return -1; } +gb_internal isize lookup_procedure_parameter(Type *type, String const ¶meter_name) { + type = base_type(type); + GB_ASSERT(type->kind == Type_Proc); + return lookup_procedure_parameter(&type->Proc, parameter_name); +} + + gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { CallArgumentError err = CallArgumentError_None; @@ -6052,7 +6059,7 @@ gb_internal bool check_named_arguments(CheckerContext *c, Type *type, Slicekind != Ast_FieldValue) { + continue; + } + ast_node(fv, FieldValue, arg); + if (fv->field->kind != Ast_Ident) { + continue; + } + String key = fv->field->Ident.token.string; + for (isize proc_index = procs.count-1; proc_index >= 0; proc_index--) { + Type *t = procs[proc_index]->type; + if (is_type_proc(t)) { + isize param_index = lookup_procedure_parameter(t, key); + if (param_index < 0) { + array_unordered_remove(&procs, proc_index); + } + } + } + } + + if (procs.count == 0) { + // if any of the named arguments are wrong, the `procs` will be empty + // just start from scratch + array_free(&procs); + procs = proc_group_entities_cloned(c, *operand); + } + + // filter by positional argument length for (isize proc_index = 0; proc_index < procs.count; /**/) { Entity *proc = procs[proc_index]; Type *pt = base_type(proc->type); @@ -6134,33 +6170,6 @@ gb_internal CallArgumentData check_call_arguments_new_and_improved_proc_group(Ch array_unordered_remove(&procs, proc_index); continue; } - - // for (Ast *arg : named_args) { - // if (arg->kind != Ast_FieldValue) { - // continue; - // } - // ast_node(fv, FieldValue, arg); - // if (fv->field->kind != Ast_Ident) { - // continue; - // } - // bool ok = false; - // String key = fv->field->Ident.token.string; - // if (param_count) for (Entity *e : pt->Proc.params->Tuple.variables) { - // if (e->token.string == key) { - // ok = true; - // break; - // } - // } - // if (!ok) { - // if (proc_index < procs.count) { - // array_unordered_remove(&procs, proc_index); - // continue; - // } else { - // break; - // } - // } - // } - proc_index++; } }