mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-20 21:35:19 +00:00
Merge pull request #1802 from odin-lang/remove-maybe-tag
Merge functionality of `#maybe` with the standard 'union' functionality
This commit is contained in:
@@ -209,7 +209,7 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
|
||||
variant := u.variants[0]
|
||||
v.id = variant.id
|
||||
ti = reflect.type_info_base(variant)
|
||||
if !(u.maybe && reflect.is_pointer(variant)) {
|
||||
if !reflect.is_pointer_internally(variant) {
|
||||
tag := any{rawptr(uintptr(v.data) + u.tag_offset), u.tag_type.id}
|
||||
assign_int(tag, 1)
|
||||
}
|
||||
|
||||
@@ -654,7 +654,7 @@ union_variant_type_info :: proc(a: any) -> ^Type_Info {
|
||||
}
|
||||
|
||||
type_info_union_is_pure_maybe :: proc(info: runtime.Type_Info_Union) -> bool {
|
||||
return info.maybe && len(info.variants) == 1 && is_pointer(info.variants[0])
|
||||
return len(info.variants) == 1 && is_pointer(info.variants[0])
|
||||
}
|
||||
|
||||
union_variant_typeid :: proc(a: any) -> typeid {
|
||||
|
||||
@@ -256,6 +256,17 @@ is_multi_pointer :: proc(info: ^Type_Info) -> bool {
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Multi_Pointer)
|
||||
return ok
|
||||
}
|
||||
is_pointer_internally :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false }
|
||||
#partial switch v in info.variant {
|
||||
case Type_Info_Pointer, Type_Info_Multi_Pointer,
|
||||
Type_Info_Procedure:
|
||||
return true
|
||||
case Type_Info_String:
|
||||
return v.is_cstring
|
||||
}
|
||||
return false
|
||||
}
|
||||
is_procedure :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false }
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Procedure)
|
||||
@@ -531,9 +542,8 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) -
|
||||
|
||||
case Type_Info_Union:
|
||||
io.write_string(w, "union ", &n) or_return
|
||||
if info.maybe {
|
||||
io.write_string(w, "#maybe ", &n) or_return
|
||||
}
|
||||
if info.no_nil { io.write_string(w, "#no_nil ", &n) or_return }
|
||||
if info.shared_nil { io.write_string(w, "#shared_nil ", &n) or_return }
|
||||
if info.custom_align {
|
||||
io.write_string(w, "#align ", &n) or_return
|
||||
io.write_i64(w, i64(ti.align), 10, &n) or_return
|
||||
|
||||
@@ -135,7 +135,6 @@ Type_Info_Union :: struct {
|
||||
|
||||
custom_align: bool,
|
||||
no_nil: bool,
|
||||
maybe: bool,
|
||||
shared_nil: bool,
|
||||
}
|
||||
Type_Info_Enum :: struct {
|
||||
|
||||
@@ -3,7 +3,7 @@ package runtime
|
||||
import "core:intrinsics"
|
||||
|
||||
@builtin
|
||||
Maybe :: union($T: typeid) #maybe {T}
|
||||
Maybe :: union($T: typeid) {T}
|
||||
|
||||
|
||||
@builtin
|
||||
|
||||
@@ -1977,15 +1977,17 @@ constant_literal_expressions :: proc() {
|
||||
}
|
||||
|
||||
union_maybe :: proc() {
|
||||
fmt.println("\n#union #maybe")
|
||||
fmt.println("\n#union based maybe")
|
||||
|
||||
// NOTE: This is already built-in, and this is just a reimplementation to explain the behaviour
|
||||
Maybe :: union($T: typeid) #maybe {T}
|
||||
Maybe :: union($T: typeid) {T}
|
||||
|
||||
i: Maybe(u8)
|
||||
p: Maybe(^u8) // No tag is stored for pointers, nil is the sentinel value
|
||||
|
||||
// Tag size will be as small as needed for the number of variants
|
||||
#assert(size_of(i) == size_of(u8) + size_of(u8))
|
||||
// No need to store a tag here, the `nil` state is shared with the variant's `nil`
|
||||
#assert(size_of(p) == size_of(^u8))
|
||||
|
||||
i = 123
|
||||
|
||||
@@ -10065,7 +10065,6 @@ gbString write_expr_to_string(gbString str, Ast *node, bool shorthand) {
|
||||
str = gb_string_appendc(str, ") ");
|
||||
}
|
||||
switch (st->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;
|
||||
}
|
||||
|
||||
@@ -620,7 +620,6 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
|
||||
doc_type.kind = OdinDocType_Union;
|
||||
if (type->Union.is_polymorphic) { doc_type.flags |= OdinDocTypeFlag_Union_polymorphic; }
|
||||
switch (type->Union.kind) {
|
||||
case UnionType_maybe: doc_type.flags |= OdinDocTypeFlag_Union_maybe; break;
|
||||
case UnionType_no_nil: doc_type.flags |= OdinDocTypeFlag_Union_no_nil; break;
|
||||
case UnionType_shared_nil: doc_type.flags |= OdinDocTypeFlag_Union_shared_nil; break;
|
||||
}
|
||||
|
||||
@@ -641,7 +641,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_union_ptr);
|
||||
|
||||
{
|
||||
LLVMValueRef vals[8] = {};
|
||||
LLVMValueRef vals[7] = {};
|
||||
|
||||
isize variant_count = gb_max(0, t->Union.variants.count);
|
||||
lbValue memory_types = lb_type_info_member_types_offset(p, variant_count);
|
||||
@@ -676,8 +676,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
|
||||
vals[4] = lb_const_bool(m, t_bool, t->Union.custom_align != 0).value;
|
||||
vals[5] = lb_const_bool(m, t_bool, t->Union.kind == UnionType_no_nil).value;
|
||||
vals[6] = lb_const_bool(m, t_bool, t->Union.kind == UnionType_maybe).value;
|
||||
vals[7] = lb_const_bool(m, t_bool, t->Union.kind == UnionType_shared_nil).value;
|
||||
vals[6] = lb_const_bool(m, t_bool, t->Union.kind == UnionType_shared_nil).value;
|
||||
|
||||
for (isize i = 0; i < gb_count_of(vals); i++) {
|
||||
if (vals[i] == nullptr) {
|
||||
|
||||
@@ -2529,6 +2529,7 @@ Ast *parse_operand(AstFile *f, bool lhs) {
|
||||
|
||||
if (maybe) {
|
||||
union_kind = UnionType_maybe;
|
||||
syntax_error(f->curr_token, "#maybe functionality has now been merged with standard 'union' functionality");
|
||||
} else if (no_nil) {
|
||||
union_kind = UnionType_no_nil;
|
||||
} else if (shared_nil) {
|
||||
|
||||
@@ -332,7 +332,7 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = {
|
||||
|
||||
enum UnionTypeKind : u8 {
|
||||
UnionType_Normal = 0,
|
||||
UnionType_maybe = 1,
|
||||
UnionType_maybe = 1, // removed
|
||||
UnionType_no_nil = 2,
|
||||
UnionType_shared_nil = 3,
|
||||
};
|
||||
|
||||
@@ -1685,11 +1685,9 @@ 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.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);
|
||||
}
|
||||
if (t->kind == Type_Union && t->Union.variants.count == 1) {
|
||||
Type *v = t->Union.variants[0];
|
||||
return is_type_internally_pointer_like(v);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1697,12 +1695,10 @@ 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.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)) {
|
||||
return type_align_of(v) == type_align_of(t);
|
||||
}
|
||||
if (t->kind == Type_Union && t->Union.variants.count == 1) {
|
||||
Type *v = t->Union.variants[0];
|
||||
if (is_type_internally_pointer_like(v)) {
|
||||
return type_align_of(v) == type_align_of(t);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -4054,7 +4050,6 @@ gbString write_type_to_string(gbString str, Type *type, bool shorthand=false) {
|
||||
case Type_Union:
|
||||
str = gb_string_appendc(str, "union");
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user