aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-03-19 13:03:14 +0000
committergingerBill <bill@gingerbill.org>2022-03-19 13:03:14 +0000
commit6d73c254b2338ab3ff4bc0a4ce8fc33f6d70a6b4 (patch)
treedbaa6439da7efa09fe69772f584a239c986d3afd /src/check_expr.cpp
parent16bd6c7205a1eea264cc2daa077f4c7f096868af (diff)
parentae6441182de5185812b9e5558b08ccaa3a877cdc (diff)
Merge branch 'master' into middle-end
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp79
1 files changed, 63 insertions, 16 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 937995df3..47cbd5354 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -4881,25 +4881,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) {
@@ -4939,6 +4930,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, &param_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;
@@ -5611,7 +5627,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, &param_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;
@@ -5641,6 +5687,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
return data;
}
+
Entity **lhs = nullptr;
isize lhs_count = -1;