diff --git a/examples/demo.odin b/examples/demo.odin index a01e96aa7..a0441921c 100644 --- a/examples/demo.odin +++ b/examples/demo.odin @@ -33,8 +33,8 @@ main :: proc() { print_f32(f.jump_height); nl() print_f32(parent.jump_height); nl() - print_name(f.entity, Vec3{1, 2, 3}) - print_name(parent.entity, Vec3{3, 2, 1}) + print_name(f, Vec3{1, 2, 3}) + print_name(parent, Vec3{3, 2, 1}) } diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 0b9c056ef..81a8a3d10 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -15,7 +15,7 @@ void update_expr_type (Checker *c, AstNode *e, Type *type, b32 fina -b32 check_is_assignable_to_using_subtype(Checker *c, Type *dst, Type *src) { +b32 check_is_assignable_to_using_subtype(Type *dst, Type *src) { Type *prev_src = src; // Type *prev_dst = dst; src = get_base_type(type_deref(src)); @@ -35,6 +35,10 @@ b32 check_is_assignable_to_using_subtype(Checker *c, Type *dst, Type *src) { return true; } } + b32 ok = check_is_assignable_to_using_subtype(dst, f->type); + if (ok) { + return true; + } } } } @@ -91,7 +95,7 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu if (is_argument) { // NOTE(bill): Polymorphism for subtyping - if (check_is_assignable_to_using_subtype(c, type, src)) { + if (check_is_assignable_to_using_subtype(type, src)) { return true; } } diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 3f02b16aa..2f7c13dd8 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -1288,7 +1288,34 @@ ssaValue *ssa_emit_string(ssaProcedure *proc, ssaValue *elem, ssaValue *len) { return str; } +String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) { + Type *prev_src = src; + // Type *prev_dst = dst; + src = get_base_type(type_deref(src)); + // dst = get_base_type(type_deref(dst)); + b32 src_is_ptr = src != prev_src; + // b32 dst_is_ptr = dst != prev_dst; + GB_ASSERT(src->kind == Type_Struct); + for (isize i = 0; i < src->Struct.field_count; i++) { + Entity *f = src->Struct.fields[i]; + if (f->kind == Entity_Variable && f->Variable.anonymous) { + if (are_types_identical(dst, f->type)) { + return f->token.string; + } + if (src_is_ptr && is_type_pointer(dst)) { + if (are_types_identical(type_deref(dst), f->type)) { + return f->token.string; + } + } + String name = lookup_polymorphic_field(info, dst, f->type); + if (name.len > 0) { + return name; + } + } + } + return make_string(""); +} ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_argument) { @@ -1394,18 +1421,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg Type *sb = get_base_type(type_deref(src)); b32 src_is_ptr = src != sb; if (sb->kind == Type_Struct) { - // NOTE(bill): Check - String field_name = {}; - for (isize i = 0; i < sb->Struct.field_count; i++) { - Entity *f = sb->Struct.fields[i]; - if (f->kind == Entity_Variable && f->Variable.anonymous) { - if (are_types_identical(t, f->type)) { - field_name = f->token.string; - break; - } - } - } - + String field_name = lookup_polymorphic_field(proc->module->info, t, src); + // gb_printf("field_name: %.*s\n", LIT(field_name)); if (field_name.len > 0) { // NOTE(bill): It can be casted Selection sel = lookup_field(sb, field_name, false);