mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 20:58:15 +00:00
Fix #4445
This commit is contained in:
+25
-18
@@ -5884,12 +5884,12 @@ typedef u32 UnpackFlags;
|
|||||||
enum UnpackFlag : u32 {
|
enum UnpackFlag : u32 {
|
||||||
UnpackFlag_None = 0,
|
UnpackFlag_None = 0,
|
||||||
UnpackFlag_AllowOk = 1<<0,
|
UnpackFlag_AllowOk = 1<<0,
|
||||||
UnpackFlag_IsVariadic = 1<<1,
|
UnpackFlag_AllowUndef = 1<<1,
|
||||||
UnpackFlag_AllowUndef = 1<<2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array<Operand> *operands, Slice<Ast *> const &rhs_arguments, UnpackFlags flags) {
|
gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array<Operand> *operands, Slice<Ast *> 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 {
|
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) {
|
if (lhs == nullptr || c->decl == nullptr) {
|
||||||
return tuple_count;
|
return tuple_count;
|
||||||
@@ -5914,11 +5914,13 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize
|
|||||||
return tuple_count;
|
return tuple_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
bool allow_ok = (flags & UnpackFlag_AllowOk) != 0;
|
bool allow_ok = (flags & UnpackFlag_AllowOk) != 0;
|
||||||
bool is_variadic = (flags & UnpackFlag_IsVariadic) != 0;
|
|
||||||
bool allow_undef = (flags & UnpackFlag_AllowUndef) != 0;
|
bool allow_undef = (flags & UnpackFlag_AllowUndef) != 0;
|
||||||
|
|
||||||
|
if (variadic_index < 0) {
|
||||||
|
variadic_index = lhs_count;
|
||||||
|
}
|
||||||
|
|
||||||
bool optional_ok = false;
|
bool optional_ok = false;
|
||||||
isize tuple_index = 0;
|
isize tuple_index = 0;
|
||||||
for (Ast *rhs : rhs_arguments) {
|
for (Ast *rhs : rhs_arguments) {
|
||||||
@@ -5934,8 +5936,7 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize
|
|||||||
|
|
||||||
Type *type_hint = nullptr;
|
Type *type_hint = nullptr;
|
||||||
|
|
||||||
|
if (lhs != nullptr && tuple_index < variadic_index) {
|
||||||
if (lhs != nullptr && tuple_index < lhs_count) {
|
|
||||||
// NOTE(bill): override DeclInfo for dependency
|
// NOTE(bill): override DeclInfo for dependency
|
||||||
Entity *e = lhs[tuple_index];
|
Entity *e = lhs[tuple_index];
|
||||||
if (e != nullptr) {
|
if (e != nullptr) {
|
||||||
@@ -5946,9 +5947,9 @@ gb_internal bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize
|
|||||||
type_hint = e->type->Slice.elem;
|
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
|
// NOTE(bill): override DeclInfo for dependency
|
||||||
Entity *e = lhs[lhs_count-1];
|
Entity *e = lhs[variadic_index];
|
||||||
if (e != nullptr) {
|
if (e != nullptr) {
|
||||||
type_hint = e->type;
|
type_hint = e->type;
|
||||||
if (e->flags & EntityFlag_Ellipsis) {
|
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;
|
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;
|
Entity **lhs = nullptr;
|
||||||
isize lhs_count = -1;
|
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));
|
GB_ASSERT(is_type_proc(proc_type));
|
||||||
TypeProc *pt = &base_type(proc_type)->Proc;
|
TypeProc *pt = &base_type(proc_type)->Proc;
|
||||||
*is_variadic = pt->variadic;
|
|
||||||
|
|
||||||
if (!pt->is_polymorphic || pt->is_poly_specialized) {
|
if (!pt->is_polymorphic || pt->is_poly_specialized) {
|
||||||
if (pt->params != nullptr) {
|
if (pt->params != nullptr) {
|
||||||
@@ -6833,7 +6833,7 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c,
|
|||||||
|
|
||||||
Entity **lhs = nullptr;
|
Entity **lhs = nullptr;
|
||||||
isize lhs_count = -1;
|
isize lhs_count = -1;
|
||||||
bool is_variadic = false;
|
i32 variadic_index = -1;
|
||||||
|
|
||||||
auto positional_operands = array_make<Operand>(heap_allocator(), 0, 0);
|
auto positional_operands = array_make<Operand>(heap_allocator(), 0, 0);
|
||||||
auto named_operands = array_make<Operand>(heap_allocator(), 0, 0);
|
auto named_operands = array_make<Operand>(heap_allocator(), 0, 0);
|
||||||
@@ -6842,9 +6842,13 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c,
|
|||||||
|
|
||||||
if (procs.count == 1) {
|
if (procs.count == 1) {
|
||||||
Entity *e = procs[0];
|
Entity *e = procs[0];
|
||||||
|
TypeProc *pt = &base_type(e->type)->Proc;
|
||||||
|
|
||||||
lhs = populate_proc_parameter_list(c, e->type, &lhs_count, &is_variadic);
|
lhs = populate_proc_parameter_list(c, e->type, &lhs_count);
|
||||||
check_unpack_arguments(c, lhs, lhs_count, &positional_operands, positional_args, is_variadic ? UnpackFlag_IsVariadic : UnpackFlag_None);
|
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)) {
|
if (check_named_arguments(c, e->type, named_args, &named_operands, true)) {
|
||||||
check_call_arguments_single(c, call, operand,
|
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) {
|
for_array(i, named_args) {
|
||||||
Ast *arg = named_args[i];
|
Ast *arg = named_args[i];
|
||||||
@@ -7347,12 +7351,15 @@ gb_internal CallArgumentData check_call_arguments(CheckerContext *c, Operand *op
|
|||||||
|
|
||||||
if (positional_args.count > 0) {
|
if (positional_args.count > 0) {
|
||||||
isize lhs_count = -1;
|
isize lhs_count = -1;
|
||||||
bool is_variadic = false;
|
|
||||||
Entity **lhs = nullptr;
|
Entity **lhs = nullptr;
|
||||||
|
i32 variadic_index = -1;
|
||||||
if (pt != nullptr) {
|
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) {
|
if (named_args.count > 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user