aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-06-26 16:48:43 +0100
committergingerBill <bill@gingerbill.org>2023-06-26 16:48:43 +0100
commit8182ba4ee05473d13c6619500457da9a1e0845ca (patch)
tree6aeff0288ae0e1ccc746078ab15fd3c0b62b0a6f /src/check_expr.cpp
parent3d9328fd79f45c85f1ecc513b2c05071f9c1d1a3 (diff)
Improve internal names for parapoly records
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index e0e78b441..b12c6d114 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -6828,15 +6828,15 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O
return err;
}
- String generated_name = make_string_c(expr_to_string(call));
-
CheckerContext ctx = *c;
// NOTE(bill): We need to make sure the lookup scope for the record is the same as where it was created
ctx.scope = polymorphic_record_parent_scope(original_type);
GB_ASSERT(ctx.scope != nullptr);
- Type *named_type = alloc_type_named(generated_name, nullptr, nullptr);
Type *bt = base_type(original_type);
+ String generated_name = make_string_c(expr_to_string(call));
+
+ Type *named_type = alloc_type_named(generated_name, nullptr, nullptr);
if (bt->kind == Type_Struct) {
Ast *node = clone_ast(bt->Struct.node);
Type *struct_type = alloc_type_struct();
@@ -6861,6 +6861,49 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O
GB_PANIC("Unsupported parametric polymorphic record type");
}
+
+ bt = base_type(named_type);
+ if (bt->kind == Type_Struct || bt->kind == Type_Union) {
+ GB_ASSERT(original_type->kind == Type_Named);
+ Entity *e = original_type->Named.type_name;
+ GB_ASSERT(e->kind == Entity_TypeName);
+
+ gbString s = gb_string_make_reserve(heap_allocator(), e->token.string.len+3);
+ s = gb_string_append_fmt(s, "%.*s(", LIT(e->token.string));
+
+ Type *params = nullptr;
+ switch (bt->kind) {
+ case Type_Struct: params = bt->Struct.polymorphic_params; break;
+ case Type_Union: params = bt->Union.polymorphic_params; break;
+ }
+
+ if (params != nullptr) for_array(i, params->Tuple.variables) {
+ Entity *v = params->Tuple.variables[i];
+ String name = v->token.string;
+ if (i > 0) {
+ s = gb_string_append_fmt(s, ", ");
+ }
+ s = gb_string_append_fmt(s, "$%.*s", LIT(name));
+
+ if (v->kind == Entity_TypeName) {
+ if (v->type->kind != Type_Generic) {
+ s = gb_string_append_fmt(s, "=");
+ s = write_type_to_string(s, v->type, false);
+ }
+ } else if (v->kind == Entity_Constant) {
+ s = gb_string_append_fmt(s, "=");
+ s = write_exact_value_to_string(s, v->Constant.value);
+ }
+ }
+ s = gb_string_append_fmt(s, ")");
+
+ String new_name = make_string_c(s);
+ named_type->Named.name = new_name;
+ if (named_type->Named.type_name) {
+ named_type->Named.type_name->token.string = new_name;
+ }
+ }
+
operand->mode = Addressing_Type;
operand->type = named_type;
}