mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Allow for cycles in record polymorphic parameters but not in actualized fields
This commit is contained in:
+44
-34
@@ -6127,47 +6127,57 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper
|
|||||||
defer (array_free(&operands));
|
defer (array_free(&operands));
|
||||||
|
|
||||||
bool named_fields = false;
|
bool named_fields = false;
|
||||||
|
{
|
||||||
|
// NOTE(bill, 2019-10-26): Allow a cycle in the parameters but not in the fields themselves
|
||||||
|
auto prev_type_path = c->type_path;
|
||||||
|
c->type_path = new_checker_type_path();
|
||||||
|
defer ({
|
||||||
|
destroy_checker_type_path(c->type_path);
|
||||||
|
c->type_path = prev_type_path;
|
||||||
|
});
|
||||||
|
|
||||||
if (is_call_expr_field_value(ce)) {
|
if (is_call_expr_field_value(ce)) {
|
||||||
named_fields = true;
|
named_fields = true;
|
||||||
operands = array_make<Operand>(heap_allocator(), ce->args.count);
|
operands = array_make<Operand>(heap_allocator(), ce->args.count);
|
||||||
for_array(i, ce->args) {
|
for_array(i, ce->args) {
|
||||||
Ast *arg = ce->args[i];
|
Ast *arg = ce->args[i];
|
||||||
ast_node(fv, FieldValue, arg);
|
ast_node(fv, FieldValue, arg);
|
||||||
|
|
||||||
if (fv->field->kind == Ast_Ident) {
|
if (fv->field->kind == Ast_Ident) {
|
||||||
String name = fv->field->Ident.token.string;
|
String name = fv->field->Ident.token.string;
|
||||||
isize index = lookup_polymorphic_record_parameter(original_type, name);
|
isize index = lookup_polymorphic_record_parameter(original_type, name);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
TypeTuple *params = get_record_polymorphic_params(original_type);
|
TypeTuple *params = get_record_polymorphic_params(original_type);
|
||||||
Entity *e = params->variables[i];
|
Entity *e = params->variables[i];
|
||||||
if (e->kind == Entity_Constant) {
|
if (e->kind == Entity_Constant) {
|
||||||
check_expr_with_type_hint(c, &operands[i], fv->value, e->type);
|
check_expr_with_type_hint(c, &operands[i], fv->value, e->type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
check_expr_or_type(c, &operands[i], fv->value);
|
||||||
}
|
}
|
||||||
check_expr_or_type(c, &operands[i], fv->value);
|
|
||||||
|
bool vari_expand = (ce->ellipsis.pos.line != 0);
|
||||||
|
if (vari_expand) {
|
||||||
|
error(ce->ellipsis, "Invalid use of '..' in a polymorphic type call'");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
operands = array_make<Operand>(heap_allocator(), 0, 2*ce->args.count);
|
||||||
|
|
||||||
|
Entity **lhs = nullptr;
|
||||||
|
isize lhs_count = -1;
|
||||||
|
|
||||||
|
TypeTuple *params = get_record_polymorphic_params(original_type);
|
||||||
|
if (params != nullptr) {
|
||||||
|
lhs = params->variables.data;
|
||||||
|
lhs_count = params->variables.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vari_expand = (ce->ellipsis.pos.line != 0);
|
|
||||||
if (vari_expand) {
|
|
||||||
error(ce->ellipsis, "Invalid use of '..' in a polymorphic type call'");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
operands = array_make<Operand>(heap_allocator(), 0, 2*ce->args.count);
|
|
||||||
|
|
||||||
Entity **lhs = nullptr;
|
|
||||||
isize lhs_count = -1;
|
|
||||||
|
|
||||||
TypeTuple *params = get_record_polymorphic_params(original_type);
|
|
||||||
if (params != nullptr) {
|
|
||||||
lhs = params->variables.data;
|
|
||||||
lhs_count = params->variables.count;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CallArgumentError err = CallArgumentError_None;
|
CallArgumentError err = CallArgumentError_None;
|
||||||
|
|||||||
Reference in New Issue
Block a user