mirror of
https://github.com/odin-lang/Odin.git
synced 2026-05-25 21:28:13 +00:00
Allow pointers to types which have subtype fields at offset 0
to be assignable in proc parameters.
```odin
// Virtual interface
IFoo :: struct {
foo: proc( self: ^IFoo ),
}
// Implements IFoo interface
Foo :: struct {
using vt: IFoo,
name: string,
}
// Implement interface via `Foo`
Foo_Impl :: IFoo {
// `self` of type `^Foo` (not `^IFoo`) is now accepted as a valid parameter.
foo = proc( self: ^Foo ) {
...
},
}
```
This commit is contained in:
@@ -4922,6 +4922,42 @@ gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isi
|
||||
return 0;
|
||||
}
|
||||
|
||||
gb_internal bool check_is_assignable_to_using_offset_zero_subtype(Type *src, Type *dst) {
|
||||
|
||||
Type *src_struct = base_type(src);
|
||||
if (!is_type_struct(src_struct)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We check multiple fields in case of #raw_union,
|
||||
// but exit on the first field that is not at offset 0.
|
||||
for_array(i, src_struct->Struct.fields) {
|
||||
Entity *f = src_struct->Struct.fields[i];
|
||||
if (f->kind != Entity_Variable || (f->flags&EntityFlags_IsSubtype) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Type *field_type = nullptr;
|
||||
i64 offset = type_offset_of(src_struct, i, &field_type);
|
||||
|
||||
// Only allowed if the subtype field shared the same address as its container
|
||||
if (offset != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (are_types_identical(field_type, dst)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check parent if the field type is a struct
|
||||
if (check_is_assignable_to_using_offset_zero_subtype(field_type, dst)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
gb_internal bool is_type_subtype_of(Type *src, Type *dst) {
|
||||
if (are_types_identical(src, dst)) {
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user