Selaa lähdekoodia

Correct the logic for parapoly records to match that of procedures (polymorphic non-typeid parameters)

gingerBill 1 vuosi sitten
vanhempi
commit
42aca72d9f
1 muutettua tiedostoa jossa 15 lisäystä ja 9 poistoa
  1. 15 9
      src/check_type.cpp

+ 15 - 9
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;
 					}
 				}