mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-05 10:14:05 +00:00
union #shared_nil
This adds a feature to `union` which requires all the variants to have a `nil` value and on assign to the union, checks whether that value is `nil` or not. If the value is `nil`, the union will be `nil` (thus sharing the `nil` value)
This commit is contained in:
@@ -165,9 +165,8 @@ struct TypeUnion {
|
||||
|
||||
i16 tag_size;
|
||||
bool is_polymorphic;
|
||||
bool is_poly_specialized : 1;
|
||||
bool no_nil : 1;
|
||||
bool maybe : 1;
|
||||
bool is_poly_specialized;
|
||||
UnionTypeKind kind;
|
||||
};
|
||||
|
||||
struct TypeProc {
|
||||
@@ -1664,7 +1663,7 @@ bool is_type_map(Type *t) {
|
||||
|
||||
bool is_type_union_maybe_pointer(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Union && t->Union.maybe) {
|
||||
if (t->kind == Type_Union && t->Union.kind == UnionType_maybe) {
|
||||
if (t->Union.variants.count == 1) {
|
||||
Type *v = t->Union.variants[0];
|
||||
return is_type_pointer(v) || is_type_multi_pointer(v);
|
||||
@@ -1676,7 +1675,7 @@ bool is_type_union_maybe_pointer(Type *t) {
|
||||
|
||||
bool is_type_union_maybe_pointer_original_alignment(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Union && t->Union.maybe) {
|
||||
if (t->kind == Type_Union && t->Union.kind == UnionType_maybe) {
|
||||
if (t->Union.variants.count == 1) {
|
||||
Type *v = t->Union.variants[0];
|
||||
if (is_type_pointer(v) || is_type_multi_pointer(v)) {
|
||||
@@ -2168,7 +2167,7 @@ bool type_has_nil(Type *t) {
|
||||
case Type_Map:
|
||||
return true;
|
||||
case Type_Union:
|
||||
return !t->Union.no_nil;
|
||||
return t->Union.kind != UnionType_no_nil;
|
||||
case Type_Struct:
|
||||
if (is_type_soa_struct(t)) {
|
||||
switch (t->Struct.soa_kind) {
|
||||
@@ -2454,7 +2453,7 @@ bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) {
|
||||
if (y->kind == Type_Union) {
|
||||
if (x->Union.variants.count == y->Union.variants.count &&
|
||||
x->Union.custom_align == y->Union.custom_align &&
|
||||
x->Union.no_nil == y->Union.no_nil) {
|
||||
x->Union.kind == y->Union.kind) {
|
||||
// NOTE(bill): zeroth variant is nullptr
|
||||
for_array(i, x->Union.variants) {
|
||||
if (!are_types_identical(x->Union.variants[i], y->Union.variants[i])) {
|
||||
@@ -2598,7 +2597,7 @@ i64 union_variant_index(Type *u, Type *v) {
|
||||
for_array(i, u->Union.variants) {
|
||||
Type *vt = u->Union.variants[i];
|
||||
if (are_types_identical(v, vt)) {
|
||||
if (u->Union.no_nil) {
|
||||
if (u->Union.kind == UnionType_no_nil) {
|
||||
return cast(i64)(i+0);
|
||||
} else {
|
||||
return cast(i64)(i+1);
|
||||
@@ -4021,8 +4020,11 @@ gbString write_type_to_string(gbString str, Type *type, bool shorthand=false) {
|
||||
|
||||
case Type_Union:
|
||||
str = gb_string_appendc(str, "union");
|
||||
if (type->Union.no_nil != 0) str = gb_string_appendc(str, " #no_nil");
|
||||
if (type->Union.maybe != 0) str = gb_string_appendc(str, " #maybe");
|
||||
switch (type->Union.kind) {
|
||||
case UnionType_maybe: str = gb_string_appendc(str, " #maybe"); break;
|
||||
case UnionType_no_nil: str = gb_string_appendc(str, " #no_nil"); break;
|
||||
case UnionType_shared_nil: str = gb_string_appendc(str, " #shared_nil"); break;
|
||||
}
|
||||
if (type->Union.custom_align != 0) str = gb_string_append_fmt(str, " #align %d", cast(int)type->Union.custom_align);
|
||||
str = gb_string_appendc(str, " {");
|
||||
for_array(i, type->Union.variants) {
|
||||
|
||||
Reference in New Issue
Block a user