diff --git a/src/check_expr.cpp b/src/check_expr.cpp index fcdabedde..71079b4a1 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5884,12 +5884,12 @@ typedef u32 UnpackFlags; enum UnpackFlag : u32 { UnpackFlag_None = 0, UnpackFlag_AllowOk = 1<<0, - UnpackFlag_IsVariadic = 1<<1, - UnpackFlag_AllowUndef = 1<<2, + UnpackFlag_AllowUndef = 1<<1, }; -gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs_arguments, UnpackFlags flags) { +gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs_arguments, UnpackFlags flags, + isize variadic_index = -1) { auto const &add_dependencies_from_unpacking = [](CheckerContext *c, Entity **lhs, isize lhs_count, isize tuple_index, isize tuple_count) -> isize { if (lhs == nullptr || c->decl == nullptr) { return tuple_count; @@ -5914,10 +5914,12 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize return tuple_count; }; - bool allow_ok = (flags & UnpackFlag_AllowOk) != 0; - bool is_variadic = (flags & UnpackFlag_IsVariadic) != 0; bool allow_undef = (flags & UnpackFlag_AllowUndef) != 0; + + if (variadic_index < 0) { + variadic_index = lhs_count; + } bool optional_ok = false; isize tuple_index = 0; @@ -5934,8 +5936,7 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize Type *type_hint = nullptr; - - if (lhs != nullptr && tuple_index < lhs_count) { + if (lhs != nullptr && tuple_index < variadic_index) { // NOTE(bill): override DeclInfo for dependency Entity *e = lhs[tuple_index]; if (e != nullptr) { @@ -5946,9 +5947,9 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize type_hint = e->type->Slice.elem; } } - } else if (lhs != nullptr && tuple_index >= lhs_count && is_variadic) { + } else if (lhs != nullptr && tuple_index >= variadic_index) { // NOTE(bill): override DeclInfo for dependency - Entity *e = lhs[lhs_count-1]; + Entity *e = lhs[variadic_index]; if (e != nullptr) { type_hint = e->type; if (e->flags & EntityFlag_Ellipsis) { @@ -6493,7 +6494,7 @@ gb_internal bool is_call_expr_field_value(AstCallExpr *ce) { return ce->args[0]->kind == Ast_FieldValue; } -gb_internal Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize *lhs_count_, bool *is_variadic) { +gb_internal Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize *lhs_count_) { Entity **lhs = nullptr; isize lhs_count = -1; @@ -6503,7 +6504,6 @@ gb_internal Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_ GB_ASSERT(is_type_proc(proc_type)); TypeProc *pt = &base_type(proc_type)->Proc; - *is_variadic = pt->variadic; if (!pt->is_polymorphic || pt->is_poly_specialized) { if (pt->params != nullptr) { @@ -6833,7 +6833,7 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, Entity **lhs = nullptr; isize lhs_count = -1; - bool is_variadic = false; + i32 variadic_index = -1; auto positional_operands = array_make(heap_allocator(), 0, 0); auto named_operands = array_make(heap_allocator(), 0, 0); @@ -6842,9 +6842,13 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, if (procs.count == 1) { Entity *e = procs[0]; - - lhs = populate_proc_parameter_list(c, e->type, &lhs_count, &is_variadic); - check_unpack_arguments(c, lhs, lhs_count, &positional_operands, positional_args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None); + TypeProc *pt = &base_type(e->type)->Proc; + + lhs = populate_proc_parameter_list(c, e->type, &lhs_count); + if (pt->variadic) { + variadic_index = pt->variadic_index; + } + check_unpack_arguments(c, lhs, lhs_count, &positional_operands, positional_args, UnpackFlag_None, variadic_index); if (check_named_arguments(c, e->type, named_args, &named_operands, true)) { check_call_arguments_single(c, call, operand, @@ -6908,7 +6912,7 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, } } - check_unpack_arguments(c, lhs, lhs_count, &positional_operands, positional_args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None); + check_unpack_arguments(c, lhs, lhs_count, &positional_operands, positional_args, UnpackFlag_None, variadic_index); for_array(i, named_args) { Ast *arg = named_args[i]; @@ -7347,12 +7351,15 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op if (positional_args.count > 0) { isize lhs_count = -1; - bool is_variadic = false; Entity **lhs = nullptr; + i32 variadic_index = -1; if (pt != nullptr) { - lhs = populate_proc_parameter_list(c, proc_type, &lhs_count, &is_variadic); + lhs = populate_proc_parameter_list(c, proc_type, &lhs_count); + if (pt->variadic) { + variadic_index = pt->variadic_index; + } } - check_unpack_arguments(c, lhs, lhs_count, &positional_operands, positional_args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None); + check_unpack_arguments(c, lhs, lhs_count, &positional_operands, positional_args, UnpackFlag_None, variadic_index); } if (named_args.count > 0) {