diff options
Diffstat (limited to 'src/check_type.cpp')
| -rw-r--r-- | src/check_type.cpp | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp index 0a2113e56..4d0901605 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1,4 +1,5 @@ gb_internal ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location); +gb_internal Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Operand const &operand); gb_internal void populate_using_array_index(CheckerContext *ctx, Ast *node, AstField *field, Type *t, String name, i32 idx) { t = base_type(t); @@ -417,11 +418,13 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly auto entities = array_make<Entity *>(permanent_allocator(), 0, variable_count); + i32 field_group_index = -1; for_array(i, params) { Ast *param = params[i]; if (param->kind != Ast_Field) { continue; } + field_group_index += 1; ast_node(p, Field, param); Ast *type_expr = p->type; Ast *default_value = unparen_expr(p->default_value); @@ -481,12 +484,12 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly type = t_invalid; } - if (is_type_polymorphic_type) { - gbString str = type_to_string(type); - error(params[i], "Parameter types cannot be polymorphic, got %s", str); - gb_string_free(str); - type = t_invalid; - } + // if (is_type_polymorphic_type) { + // gbString str = type_to_string(type); + // error(params[i], "Parameter types cannot be polymorphic, got %s", str); + // gb_string_free(str); + // type = t_invalid; + // } if (!is_type_param && check_constant_parameter_value(type, params[i])) { // failed @@ -523,13 +526,15 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly e->TypeName.is_type_alias = true; e->flags |= EntityFlag_PolyConst; } else { - if (is_type_polymorphic(base_type(operand.type))) { + Type *t = determine_type_from_polymorphic(ctx, type, operand); + if (is_type_polymorphic(base_type(t))) { *is_polymorphic_ = true; can_check_fields = false; } if (e == nullptr) { - e = alloc_entity_constant(scope, token, operand.type, operand.value); + e = alloc_entity_const_param(scope, token, t, operand.value, is_type_polymorphic(t)); e->Constant.param_value = param_value; + e->Constant.field_group_index = field_group_index; } } } else { @@ -538,7 +543,8 @@ gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *poly e->TypeName.is_type_alias = true; e->flags |= EntityFlag_PolyConst; } else { - e = alloc_entity_constant(scope, token, type, param_value.value); + e = alloc_entity_const_param(scope, token, type, param_value.value, is_type_polymorphic(type)); + e->Constant.field_group_index = field_group_index; e->Constant.param_value = param_value; } } |