diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 7c37fa7616..9e7bfc99ba 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -226,11 +226,10 @@ pub const TypeInfo = union(enum) { child: type, is_allowzero: bool, - /// This field is an optional type. /// The type of the sentinel is the element type of the pointer, which is /// the value of the `child` field in this struct. However there is no way - /// to refer to that type here, so we use `anytype`. - sentinel: anytype, + /// to refer to that type here, so we use pointer to `anyopaque`. + sentinel: ?*const anyopaque, /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. @@ -248,11 +247,10 @@ pub const TypeInfo = union(enum) { len: comptime_int, child: type, - /// This field is an optional type. /// The type of the sentinel is the element type of the array, which is /// the value of the `child` field in this struct. However there is no way - /// to refer to that type here, so we use `anytype`. - sentinel: anytype, + /// to refer to that type here, so we use pointer to `anyopaque`. + sentinel: ?*const anyopaque, }; /// This data structure is used by the Zig language code generation and @@ -267,8 +265,9 @@ pub const TypeInfo = union(enum) { /// therefore must be kept in sync with the compiler implementation. pub const StructField = struct { name: []const u8, + /// TODO rename to `type` field_type: type, - default_value: anytype, + default_value: ?*const anyopaque, is_comptime: bool, alignment: comptime_int, }; @@ -369,7 +368,7 @@ pub const TypeInfo = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const Frame = struct { - function: anytype, + function: *const anyopaque, }; /// This data structure is used by the Zig language code generation and diff --git a/lib/std/enums.zig b/lib/std/enums.zig index cfcc8e4f1d..9ac80bd907 100644 --- a/lib/std/enums.zig +++ b/lib/std/enums.zig @@ -16,7 +16,7 @@ pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_def fields = fields ++ &[_]StructField{.{ .name = field.name, .field_type = Data, - .default_value = field_default, + .default_value = if (field_default) |d| &d else null, .is_comptime = false, .alignment = if (@sizeOf(Data) > 0) @alignOf(Data) else 0, }}; diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 03dc27ea53..71de42aad7 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -296,7 +296,8 @@ pub fn zeroes(comptime T: type) T { } }, .Array => |info| { - if (info.sentinel) |sentinel| { + if (info.sentinel) |sentinel_ptr| { + const sentinel = @ptrCast(*const info.child, sentinel_ptr).*; return [_:sentinel]info.child{zeroes(info.child)} ** info.len; } return [_]info.child{zeroes(info.child)} ** info.len; @@ -453,7 +454,8 @@ pub fn zeroInit(comptime T: type, init: anytype) T { @field(value, field.name) = @field(init, field.name); }, } - } else if (field.default_value) |default_value| { + } else if (field.default_value) |default_value_ptr| { + const default_value = @ptrCast(*const field.field_type, default_value_ptr).*; @field(value, field.name) = default_value; } } @@ -599,7 +601,7 @@ pub fn Span(comptime T: type) type { else => @compileError("invalid type given to std.mem.Span"), }, .C => { - new_ptr_info.sentinel = 0; + new_ptr_info.sentinel = &@as(ptr_info.child, 0); new_ptr_info.is_allowzero = false; }, .Many, .Slice => {}, @@ -651,7 +653,9 @@ pub fn span(ptr: anytype) Span(@TypeOf(ptr)) { } const Result = Span(@TypeOf(ptr)); const l = len(ptr); - if (@typeInfo(Result).Pointer.sentinel) |s| { + const ptr_info = @typeInfo(Result).Pointer; + if (ptr_info.sentinel) |s_ptr| { + const s = @ptrCast(*const ptr_info.child, s_ptr).*; return ptr[0..l :s]; } else { return ptr[0..l]; @@ -684,9 +688,10 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type { // The return type must only be sentinel terminated if we are guaranteed // to find the value searched for, which is only the case if it matches // the sentinel of the type passed. - if (array_info.sentinel) |sentinel| { + if (array_info.sentinel) |sentinel_ptr| { + const sentinel = @ptrCast(*const array_info.child, sentinel_ptr).*; if (end == sentinel) { - new_ptr_info.sentinel = end; + new_ptr_info.sentinel = &end; } else { new_ptr_info.sentinel = null; } @@ -698,16 +703,17 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type { // The return type must only be sentinel terminated if we are guaranteed // to find the value searched for, which is only the case if it matches // the sentinel of the type passed. - if (ptr_info.sentinel) |sentinel| { + if (ptr_info.sentinel) |sentinel_ptr| { + const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*; if (end == sentinel) { - new_ptr_info.sentinel = end; + new_ptr_info.sentinel = &end; } else { new_ptr_info.sentinel = null; } } }, .C => { - new_ptr_info.sentinel = end; + new_ptr_info.sentinel = &end; // C pointers are always allowzero, but we don't want the return type to be. assert(new_ptr_info.is_allowzero); new_ptr_info.is_allowzero = false; @@ -734,7 +740,9 @@ pub fn sliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) SliceTo(@Typ } const Result = SliceTo(@TypeOf(ptr), end); const length = lenSliceTo(ptr, end); - if (@typeInfo(Result).Pointer.sentinel) |s| { + const ptr_info = @typeInfo(Result).Pointer; + if (ptr_info.sentinel) |s_ptr| { + const s = @ptrCast(*const ptr_info.child, s_ptr).*; return ptr[0..length :s]; } else { return ptr[0..length]; @@ -786,7 +794,8 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { .Pointer => |ptr_info| switch (ptr_info.size) { .One => switch (@typeInfo(ptr_info.child)) { .Array => |array_info| { - if (array_info.sentinel) |sentinel| { + if (array_info.sentinel) |sentinel_ptr| { + const sentinel = @ptrCast(*const array_info.child, sentinel_ptr).*; if (sentinel == end) { return indexOfSentinel(array_info.child, end, ptr); } @@ -795,7 +804,8 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { }, else => {}, }, - .Many => if (ptr_info.sentinel) |sentinel| { + .Many => if (ptr_info.sentinel) |sentinel_ptr| { + const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*; // We may be looking for something other than the sentinel, // but iterating past the sentinel would be a bug so we need // to check for both. @@ -808,7 +818,8 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { return indexOfSentinel(ptr_info.child, end, ptr); }, .Slice => { - if (ptr_info.sentinel) |sentinel| { + if (ptr_info.sentinel) |sentinel_ptr| { + const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*; if (sentinel == end) { return indexOfSentinel(ptr_info.child, sentinel, ptr); } @@ -867,10 +878,12 @@ pub fn len(value: anytype) usize { .Array => value.len, else => @compileError("invalid type given to std.mem.len"), }, - .Many => if (info.sentinel) |sentinel| - indexOfSentinel(info.child, sentinel, value) - else - @compileError("length of pointer with no sentinel"), + .Many => { + const sentinel_ptr = info.sentinel orelse + @compileError("length of pointer with no sentinel"); + const sentinel = @ptrCast(*const info.child, sentinel_ptr).*; + return indexOfSentinel(info.child, sentinel, value); + }, .C => { assert(value != null); return indexOfSentinel(info.child, 0, value); @@ -2572,7 +2585,11 @@ test "alignPointer" { try S.checkAlign([*]u32, math.maxInt(usize) - 3, 8, 0); } -fn CopyPtrAttrs(comptime source: type, comptime size: std.builtin.TypeInfo.Pointer.Size, comptime child: type) type { +fn CopyPtrAttrs( + comptime source: type, + comptime size: std.builtin.TypeInfo.Pointer.Size, + comptime child: type, +) type { const info = @typeInfo(source).Pointer; return @Type(.{ .Pointer = .{ diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 72a073fbfb..03825e2140 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -190,12 +190,21 @@ test "std.meta.Elem" { /// Types which cannot possibly have a sentinel will be a compile error. pub fn sentinel(comptime T: type) ?Elem(T) { switch (@typeInfo(T)) { - .Array => |info| return info.sentinel, + .Array => |info| { + const sentinel_ptr = info.sentinel orelse return null; + return @ptrCast(*const info.child, sentinel_ptr).*; + }, .Pointer => |info| { switch (info.size) { - .Many, .Slice => return info.sentinel, + .Many, .Slice => { + const sentinel_ptr = info.sentinel orelse return null; + return @ptrCast(*const info.child, sentinel_ptr).*; + }, .One => switch (@typeInfo(info.child)) { - .Array => |array_info| return array_info.sentinel, + .Array => |array_info| { + const sentinel_ptr = array_info.sentinel orelse return null; + return @ptrCast(*const array_info.child, sentinel_ptr).*; + }, else => {}, }, else => {}, @@ -239,7 +248,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { .Array = .{ .len = array_info.len, .child = array_info.child, - .sentinel = sentinel_val, + .sentinel = &sentinel_val, }, }), .is_allowzero = info.is_allowzero, @@ -257,7 +266,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { .address_space = info.address_space, .child = info.child, .is_allowzero = info.is_allowzero, - .sentinel = sentinel_val, + .sentinel = &sentinel_val, }, }), else => {}, @@ -275,7 +284,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { .address_space = ptr_info.address_space, .child = ptr_info.child, .is_allowzero = ptr_info.is_allowzero, - .sentinel = sentinel_val, + .sentinel = &sentinel_val, }, }), }, diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index b7a48a705c..b3c578d95a 100644 --- a/src/stage1/all_types.hpp +++ b/src/stage1/all_types.hpp @@ -2108,6 +2108,7 @@ struct CodeGen { ZigType *entry_global_error_set; ZigType *entry_enum_literal; ZigType *entry_any_frame; + ZigType *entry_opt_ptr_const_anyopaque; } builtin_types; struct Intern { diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index b97f009d62..154e982ff9 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -9451,6 +9451,12 @@ static void define_builtin_types(CodeGen *g) { g->primitive_type_table.put(&g->builtin_types.entry_anyopaque->name, g->builtin_types.entry_anyopaque); } + { + ZigType *ptr_const_anyopaque = get_pointer_to_type(g, + g->builtin_types.entry_anyopaque, true); + g->builtin_types.entry_opt_ptr_const_anyopaque = get_optional_type(g, ptr_const_anyopaque); + } + { ZigType *entry = new_type_table_entry(ZigTypeIdErrorSet); buf_init_from_str(&entry->name, "anyerror"); diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 1faf11680e..89f7de9d4d 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -18045,11 +18045,12 @@ static PtrLen size_enum_index_to_ptr_len(BuiltinPtrSize size_enum_index) { } static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ptr_type_entry) { + CodeGen *g = ira->codegen; ZigType *attrs_type; BuiltinPtrSize size_enum_index; if (is_slice(ptr_type_entry)) { TypeStructField *ptr_field = ptr_type_entry->data.structure.fields[slice_ptr_index]; - attrs_type = resolve_struct_field_type(ira->codegen, ptr_field); + attrs_type = resolve_struct_field_type(g, ptr_field); size_enum_index = BuiltinPtrSizeSlice; } else if (ptr_type_entry->id == ZigTypeIdPointer) { attrs_type = ptr_type_entry; @@ -18059,19 +18060,19 @@ static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, Scope *scope, AstNode } ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); - assertNoError(type_resolve(ira->codegen, type_info_pointer_type, ResolveStatusSizeKnown)); + assertNoError(type_resolve(g, type_info_pointer_type, ResolveStatusSizeKnown)); - ZigValue *result = ira->codegen->pass1_arena->create(); + ZigValue *result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = type_info_pointer_type; - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 8); + ZigValue **fields = alloc_const_vals_ptrs(g, 8); result->data.x_struct.fields = fields; // size: Size ensure_field_index(result->type, "size", 0); ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); - assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown)); + assertNoError(type_resolve(g, type_info_pointer_size_type, ResolveStatusSizeKnown)); fields[0]->special = ConstValSpecialStatic; fields[0]->type = type_info_pointer_size_type; bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index); @@ -18079,16 +18080,16 @@ static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, Scope *scope, AstNode // is_const: bool ensure_field_index(result->type, "is_const", 1); fields[1]->special = ConstValSpecialStatic; - fields[1]->type = ira->codegen->builtin_types.entry_bool; + fields[1]->type = g->builtin_types.entry_bool; fields[1]->data.x_bool = attrs_type->data.pointer.is_const; // is_volatile: bool ensure_field_index(result->type, "is_volatile", 2); fields[2]->special = ConstValSpecialStatic; - fields[2]->type = ira->codegen->builtin_types.entry_bool; + fields[2]->type = g->builtin_types.entry_bool; fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile; // alignment: comptime_int ensure_field_index(result->type, "alignment", 3); - fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int; + fields[3]->type = g->builtin_types.entry_num_lit_int; if (attrs_type->data.pointer.explicit_alignment != 0) { fields[3]->special = ConstValSpecialStatic; bigint_init_unsigned(&fields[3]->data.x_bigint, attrs_type->data.pointer.explicit_alignment); @@ -18103,27 +18104,25 @@ static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, Scope *scope, AstNode // address_space: AddressSpace, ensure_field_index(result->type, "address_space", 4); fields[4]->special = ConstValSpecialStatic; - fields[4]->type = get_builtin_type(ira->codegen, "AddressSpace"); + fields[4]->type = get_builtin_type(g, "AddressSpace"); bigint_init_unsigned(&fields[4]->data.x_enum_tag, AddressSpaceGeneric); // child: type ensure_field_index(result->type, "child", 5); fields[5]->special = ConstValSpecialStatic; - fields[5]->type = ira->codegen->builtin_types.entry_type; + fields[5]->type = g->builtin_types.entry_type; fields[5]->data.x_type = attrs_type->data.pointer.child_type; // is_allowzero: bool ensure_field_index(result->type, "is_allowzero", 6); fields[6]->special = ConstValSpecialStatic; - fields[6]->type = ira->codegen->builtin_types.entry_bool; + fields[6]->type = g->builtin_types.entry_bool; fields[6]->data.x_bool = attrs_type->data.pointer.allow_zero; - // sentinel: anytype + // sentinel: ?*const anyopaque ensure_field_index(result->type, "sentinel", 7); fields[7]->special = ConstValSpecialStatic; - if (attrs_type->data.pointer.sentinel != nullptr) { - fields[7]->type = get_optional_type(ira->codegen, attrs_type->data.pointer.child_type); - set_optional_payload(fields[7], attrs_type->data.pointer.sentinel); - } else { - fields[7]->type = ira->codegen->builtin_types.entry_null; - } + fields[7]->type = g->builtin_types.entry_opt_ptr_const_anyopaque; + ZigValue *ptr_to_sent = (attrs_type->data.pointer.sentinel == nullptr) ? nullptr : + create_const_ptr_ref(g, attrs_type->data.pointer.sentinel, true); + set_optional_payload(fields[7], ptr_to_sent); return result; }; @@ -18153,7 +18152,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); - auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); + CodeGen *g = ira->codegen; + + auto entry = g->type_info_cache.maybe_get(type_entry); if (entry != nullptr) { *out = entry->value; return ErrorNone; @@ -18172,43 +18173,43 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour case ZigTypeIdEnumLiteral: case ZigTypeIdUndefined: case ZigTypeIdNull: - result = ira->codegen->intern.for_void(); + result = g->intern.for_void(); break; case ZigTypeIdInt: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Int", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); + ZigValue **fields = alloc_const_vals_ptrs(g, 2); result->data.x_struct.fields = fields; // is_signed: Signedness ensure_field_index(result->type, "signedness", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = get_builtin_type(ira->codegen, "Signedness"); + fields[0]->type = get_builtin_type(g, "Signedness"); bigint_init_unsigned(&fields[0]->data.x_enum_tag, !type_entry->data.integral.is_signed); // bits: u8 ensure_field_index(result->type, "bits", 1); fields[1]->special = ConstValSpecialStatic; - fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; + fields[1]->type = g->builtin_types.entry_num_lit_int; bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count); break; } case ZigTypeIdFloat: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Float", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); + ZigValue **fields = alloc_const_vals_ptrs(g, 1); result->data.x_struct.fields = fields; // bits: u8 ensure_field_index(result->type, "bits", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; + fields[0]->type = g->builtin_types.entry_num_lit_int; bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count); break; @@ -18222,97 +18223,96 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour } case ZigTypeIdArray: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Array", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3); + ZigValue **fields = alloc_const_vals_ptrs(g, 3); result->data.x_struct.fields = fields; // len: usize ensure_field_index(result->type, "len", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; + fields[0]->type = g->builtin_types.entry_num_lit_int; bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len); // child: type ensure_field_index(result->type, "child", 1); fields[1]->special = ConstValSpecialStatic; - fields[1]->type = ira->codegen->builtin_types.entry_type; + fields[1]->type = g->builtin_types.entry_type; fields[1]->data.x_type = type_entry->data.array.child_type; - // sentinel: anytype + src_assert(type_entry->data.array.child_type != nullptr, source_node); + // sentinel: ?*const anyopaque fields[2]->special = ConstValSpecialStatic; - if (type_entry->data.array.child_type != nullptr) { - fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type); - set_optional_payload(fields[2], type_entry->data.array.sentinel); - } else { - fields[2]->type = ira->codegen->builtin_types.entry_null; - } + fields[2]->type = g->builtin_types.entry_opt_ptr_const_anyopaque; + ZigValue *ptr_to_sent = (type_entry->data.array.sentinel == nullptr) ? nullptr : + create_const_ptr_ref(g, type_entry->data.array.sentinel, true); + set_optional_payload(fields[2], ptr_to_sent); break; } case ZigTypeIdVector: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Vector", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); + ZigValue **fields = alloc_const_vals_ptrs(g, 2); result->data.x_struct.fields = fields; // len: usize ensure_field_index(result->type, "len", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; + fields[0]->type = g->builtin_types.entry_num_lit_int; bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len); // child: type ensure_field_index(result->type, "child", 1); fields[1]->special = ConstValSpecialStatic; - fields[1]->type = ira->codegen->builtin_types.entry_type; + fields[1]->type = g->builtin_types.entry_type; fields[1]->data.x_type = type_entry->data.vector.elem_type; break; } case ZigTypeIdOptional: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Optional", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); + ZigValue **fields = alloc_const_vals_ptrs(g, 1); result->data.x_struct.fields = fields; // child: type ensure_field_index(result->type, "child", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = ira->codegen->builtin_types.entry_type; + fields[0]->type = g->builtin_types.entry_type; fields[0]->data.x_type = type_entry->data.maybe.child_type; break; } case ZigTypeIdAnyFrame: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); + ZigValue **fields = alloc_const_vals_ptrs(g, 1); result->data.x_struct.fields = fields; // child: ?type ensure_field_index(result->type, "child", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + fields[0]->type = get_optional_type(g, g->builtin_types.entry_type); fields[0]->data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : - create_const_type(ira->codegen, type_entry->data.any_frame.result_type); + create_const_type(g, type_entry->data.any_frame.result_type); break; } case ZigTypeIdEnum: { - if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) + if ((err = type_resolve(g, type_entry, ResolveStatusSizeKnown))) return err; - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Enum", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); + ZigValue **fields = alloc_const_vals_ptrs(g, 5); result->data.x_struct.fields = fields; // layout: ContainerLayout @@ -18323,24 +18323,24 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour // tag_type: type ensure_field_index(result->type, "tag_type", 1); fields[1]->special = ConstValSpecialStatic; - fields[1]->type = ira->codegen->builtin_types.entry_type; + fields[1]->type = g->builtin_types.entry_type; fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type; // fields: []TypeInfo.EnumField ensure_field_index(result->type, "fields", 2); ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); - if ((err = type_resolve(ira->codegen, type_info_enum_field_type, ResolveStatusSizeKnown))) { + if ((err = type_resolve(g, type_info_enum_field_type, ResolveStatusSizeKnown))) { zig_unreachable(); } uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; - ZigValue *enum_field_array = ira->codegen->pass1_arena->create(); + ZigValue *enum_field_array = g->pass1_arena->create(); enum_field_array->special = ConstValSpecialStatic; - enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count, nullptr); + enum_field_array->type = get_array_type(g, type_info_enum_field_type, enum_field_count, nullptr); enum_field_array->data.x_array.special = ConstArraySpecialNone; - enum_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate(enum_field_count); + enum_field_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate(enum_field_count); - init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false, nullptr); + init_const_slice(g, fields[2], enum_field_array, 0, enum_field_count, false, nullptr); for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) { @@ -18361,39 +18361,39 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour // is_exhaustive: bool ensure_field_index(result->type, "is_exhaustive", 4); fields[4]->special = ConstValSpecialStatic; - fields[4]->type = ira->codegen->builtin_types.entry_bool; + fields[4]->type = g->builtin_types.entry_bool; fields[4]->data.x_bool = !type_entry->data.enumeration.non_exhaustive; break; } case ZigTypeIdErrorSet: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); - if (!resolve_inferred_error_set(ira->codegen, type_entry, source_node)) { + if (!resolve_inferred_error_set(g, type_entry, source_node)) { return ErrorSemanticAnalyzeFail; } if (type_is_global_error_set(type_entry)) { result->data.x_optional = nullptr; break; } - if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { + if ((err = type_resolve(g, type_info_error_type, ResolveStatusSizeKnown))) { zig_unreachable(); } - ZigValue *slice_val = ira->codegen->pass1_arena->create(); + ZigValue *slice_val = g->pass1_arena->create(); result->data.x_optional = slice_val; uint32_t error_count = type_entry->data.error_set.err_count; - ZigValue *error_array = ira->codegen->pass1_arena->create(); + ZigValue *error_array = g->pass1_arena->create(); error_array->special = ConstValSpecialStatic; - error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count, nullptr); + error_array->type = get_array_type(g, type_info_error_type, error_count, nullptr); error_array->data.x_array.special = ConstArraySpecialNone; - error_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate(error_count); + error_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate(error_count); - init_const_slice(ira->codegen, slice_val, error_array, 0, error_count, false, nullptr); + init_const_slice(g, slice_val, error_array, 0, error_count, false, nullptr); for (uint32_t error_index = 0; error_index < error_count; error_index++) { ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; ZigValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; @@ -18401,14 +18401,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour error_val->special = ConstValSpecialStatic; error_val->type = type_info_error_type; - ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 1); + ZigValue **inner_fields = alloc_const_vals_ptrs(g, 1); ZigValue *name = nullptr; if (error->cached_error_name_val != nullptr) name = error->cached_error_name_val; if (name == nullptr) - name = create_const_str_lit(ira->codegen, &error->name)->data.x_ptr.data.ref.pointee; - init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true, nullptr); + name = create_const_str_lit(g, &error->name)->data.x_ptr.data.ref.pointee; + init_const_slice(g, inner_fields[0], name, 0, buf_len(&error->name), true, nullptr); error_val->data.x_struct.fields = inner_fields; error_val->parent.id = ConstParentIdArray; @@ -18420,37 +18420,37 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour } case ZigTypeIdErrorUnion: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); + ZigValue **fields = alloc_const_vals_ptrs(g, 2); result->data.x_struct.fields = fields; // error_set: type ensure_field_index(result->type, "error_set", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = ira->codegen->builtin_types.entry_type; + fields[0]->type = g->builtin_types.entry_type; fields[0]->data.x_type = type_entry->data.error_union.err_set_type; // payload: type ensure_field_index(result->type, "payload", 1); fields[1]->special = ConstValSpecialStatic; - fields[1]->type = ira->codegen->builtin_types.entry_type; + fields[1]->type = g->builtin_types.entry_type; fields[1]->data.x_type = type_entry->data.error_union.payload_type; break; } case ZigTypeIdUnion: { - if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) + if ((err = type_resolve(g, type_entry, ResolveStatusSizeKnown))) return err; - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Union", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); + ZigValue **fields = alloc_const_vals_ptrs(g, 4); result->data.x_struct.fields = fields; // layout: ContainerLayout @@ -18461,15 +18461,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour // tag_type: ?type ensure_field_index(result->type, "tag_type", 1); fields[1]->special = ConstValSpecialStatic; - fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + fields[1]->type = get_optional_type(g, g->builtin_types.entry_type); AstNode *union_decl_node = type_entry->data.unionation.decl_node; if (union_decl_node->data.container_decl.auto_enum || union_decl_node->data.container_decl.init_arg_expr != nullptr) { - ZigValue *tag_type = ira->codegen->pass1_arena->create(); + ZigValue *tag_type = g->pass1_arena->create(); tag_type->special = ConstValSpecialStatic; - tag_type->type = ira->codegen->builtin_types.entry_type; + tag_type->type = g->builtin_types.entry_type; tag_type->data.x_type = type_entry->data.unionation.tag_type; fields[1]->data.x_optional = tag_type; } else { @@ -18479,17 +18479,17 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour ensure_field_index(result->type, "fields", 2); ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); - if ((err = type_resolve(ira->codegen, type_info_union_field_type, ResolveStatusSizeKnown))) + if ((err = type_resolve(g, type_info_union_field_type, ResolveStatusSizeKnown))) zig_unreachable(); uint32_t union_field_count = type_entry->data.unionation.src_field_count; - ZigValue *union_field_array = ira->codegen->pass1_arena->create(); + ZigValue *union_field_array = g->pass1_arena->create(); union_field_array->special = ConstValSpecialStatic; - union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count, nullptr); + union_field_array->type = get_array_type(g, type_info_union_field_type, union_field_count, nullptr); union_field_array->data.x_array.special = ConstArraySpecialNone; - union_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate(union_field_count); + union_field_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate(union_field_count); - init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false, nullptr); + init_const_slice(g, fields[2], union_field_array, 0, union_field_count, false, nullptr); for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; @@ -18498,19 +18498,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour union_field_val->special = ConstValSpecialStatic; union_field_val->type = type_info_union_field_type; - ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); + ZigValue **inner_fields = alloc_const_vals_ptrs(g, 3); // field_type: type inner_fields[1]->special = ConstValSpecialStatic; - inner_fields[1]->type = ira->codegen->builtin_types.entry_type; + inner_fields[1]->type = g->builtin_types.entry_type; inner_fields[1]->data.x_type = union_field->type_entry; // alignment: comptime_int inner_fields[2]->special = ConstValSpecialStatic; - inner_fields[2]->type = ira->codegen->builtin_types.entry_num_lit_int; + inner_fields[2]->type = g->builtin_types.entry_num_lit_int; bigint_init_unsigned(&inner_fields[2]->data.x_bigint, union_field->align); - ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee; - init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true, nullptr); + ZigValue *name = create_const_str_lit(g, union_field->name)->data.x_ptr.data.ref.pointee; + init_const_slice(g, inner_fields[0], name, 0, buf_len(union_field->name), true, nullptr); union_field_val->data.x_struct.fields = inner_fields; union_field_val->parent.id = ConstParentIdArray; @@ -18536,14 +18536,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour break; } - if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) + if ((err = type_resolve(g, type_entry, ResolveStatusSizeKnown))) return err; - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Struct", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); + ZigValue **fields = alloc_const_vals_ptrs(g, 4); result->data.x_struct.fields = fields; // layout: ContainerLayout @@ -18555,18 +18555,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour ensure_field_index(result->type, "fields", 1); ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); - if ((err = type_resolve(ira->codegen, type_info_struct_field_type, ResolveStatusSizeKnown))) { + if ((err = type_resolve(g, type_info_struct_field_type, ResolveStatusSizeKnown))) { zig_unreachable(); } uint32_t struct_field_count = type_entry->data.structure.src_field_count; - ZigValue *struct_field_array = ira->codegen->pass1_arena->create(); + ZigValue *struct_field_array = g->pass1_arena->create(); struct_field_array->special = ConstValSpecialStatic; - struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count, nullptr); + struct_field_array->type = get_array_type(g, type_info_struct_field_type, struct_field_count, nullptr); struct_field_array->data.x_array.special = ConstArraySpecialNone; - struct_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate(struct_field_count); + struct_field_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate(struct_field_count); - init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false, nullptr); + init_const_slice(g, fields[1], struct_field_array, 0, struct_field_count, false, nullptr); for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { TypeStructField *struct_field = type_entry->data.structure.fields[struct_field_index]; @@ -18575,34 +18575,37 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour struct_field_val->special = ConstValSpecialStatic; struct_field_val->type = type_info_struct_field_type; - ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 5); + ZigValue **inner_fields = alloc_const_vals_ptrs(g, 5); inner_fields[1]->special = ConstValSpecialStatic; - inner_fields[1]->type = ira->codegen->builtin_types.entry_type; + inner_fields[1]->type = g->builtin_types.entry_type; inner_fields[1]->data.x_type = struct_field->type_entry; - // default_value: anytype + // default_value: ?*const anyopaque inner_fields[2]->special = ConstValSpecialStatic; - inner_fields[2]->type = get_optional_type2(ira->codegen, struct_field->type_entry); - if (inner_fields[2]->type == nullptr) return ErrorSemanticAnalyzeFail; - memoize_field_init_val(ira->codegen, type_entry, struct_field); - if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){ + inner_fields[2]->type = g->builtin_types.entry_opt_ptr_const_anyopaque; + memoize_field_init_val(g, type_entry, struct_field); + if (struct_field->init_val != nullptr && + type_is_invalid(struct_field->init_val->type)) + { return ErrorSemanticAnalyzeFail; } - set_optional_payload(inner_fields[2], struct_field->init_val); + ZigValue *ptr_to_sent = (struct_field->init_val == nullptr) ? nullptr : + create_const_ptr_ref(g, struct_field->init_val, true); + set_optional_payload(inner_fields[2], ptr_to_sent); // is_comptime: bool inner_fields[3]->special = ConstValSpecialStatic; - inner_fields[3]->type = ira->codegen->builtin_types.entry_bool; + inner_fields[3]->type = g->builtin_types.entry_bool; inner_fields[3]->data.x_bool = struct_field->is_comptime; // alignment: comptime_int inner_fields[4]->special = ConstValSpecialStatic; - inner_fields[4]->type = ira->codegen->builtin_types.entry_num_lit_int; + inner_fields[4]->type = g->builtin_types.entry_num_lit_int; bigint_init_unsigned(&inner_fields[4]->data.x_bigint, struct_field->align); - ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee; - init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true, nullptr); + ZigValue *name = create_const_str_lit(g, struct_field->name)->data.x_ptr.data.ref.pointee; + init_const_slice(g, inner_fields[0], name, 0, buf_len(struct_field->name), true, nullptr); struct_field_val->data.x_struct.fields = inner_fields; struct_field_val->parent.id = ConstParentIdArray; @@ -18620,69 +18623,69 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour // is_tuple: bool ensure_field_index(result->type, "is_tuple", 3); fields[3]->special = ConstValSpecialStatic; - fields[3]->type = ira->codegen->builtin_types.entry_bool; + fields[3]->type = g->builtin_types.entry_bool; fields[3]->data.x_bool = is_tuple(type_entry); break; } case ZigTypeIdFn: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Fn", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 7); + ZigValue **fields = alloc_const_vals_ptrs(g, 7); result->data.x_struct.fields = fields; // calling_convention: TypeInfo.CallingConvention ensure_field_index(result->type, "calling_convention", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention"); + fields[0]->type = get_builtin_type(g, "CallingConvention"); bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); // alignment: comptime_int ensure_field_index(result->type, "alignment", 1); fields[1]->special = ConstValSpecialStatic; - fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; - bigint_init_unsigned(&fields[1]->data.x_bigint, get_ptr_align(ira->codegen, type_entry)); + fields[1]->type = g->builtin_types.entry_num_lit_int; + bigint_init_unsigned(&fields[1]->data.x_bigint, get_ptr_align(g, type_entry)); // is_generic: bool ensure_field_index(result->type, "is_generic", 2); bool is_generic = type_entry->data.fn.is_generic; fields[2]->special = ConstValSpecialStatic; - fields[2]->type = ira->codegen->builtin_types.entry_bool; + fields[2]->type = g->builtin_types.entry_bool; fields[2]->data.x_bool = is_generic; // is_varargs: bool ensure_field_index(result->type, "is_var_args", 3); bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; fields[3]->special = ConstValSpecialStatic; - fields[3]->type = ira->codegen->builtin_types.entry_bool; + fields[3]->type = g->builtin_types.entry_bool; fields[3]->data.x_bool = is_varargs; // return_type: ?type ensure_field_index(result->type, "return_type", 4); fields[4]->special = ConstValSpecialStatic; - fields[4]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + fields[4]->type = get_optional_type(g, g->builtin_types.entry_type); if (type_entry->data.fn.fn_type_id.return_type == nullptr) fields[4]->data.x_optional = nullptr; else { - ZigValue *return_type = ira->codegen->pass1_arena->create(); + ZigValue *return_type = g->pass1_arena->create(); return_type->special = ConstValSpecialStatic; - return_type->type = ira->codegen->builtin_types.entry_type; + return_type->type = g->builtin_types.entry_type; return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; fields[4]->data.x_optional = return_type; } // args: []TypeInfo.FnArg ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); - if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { + if ((err = type_resolve(g, type_info_fn_arg_type, ResolveStatusSizeKnown))) { zig_unreachable(); } size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count; - ZigValue *fn_arg_array = ira->codegen->pass1_arena->create(); + ZigValue *fn_arg_array = g->pass1_arena->create(); fn_arg_array->special = ConstValSpecialStatic; - fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count, nullptr); + fn_arg_array->type = get_array_type(g, type_info_fn_arg_type, fn_arg_count, nullptr); fn_arg_array->data.x_array.special = ConstArraySpecialNone; - fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate(fn_arg_count); + fn_arg_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate(fn_arg_count); - init_const_slice(ira->codegen, fields[5], fn_arg_array, 0, fn_arg_count, false, nullptr); + init_const_slice(g, fields[5], fn_arg_array, 0, fn_arg_count, false, nullptr); for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; @@ -18694,22 +18697,22 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour bool arg_is_generic = fn_param_info->type == nullptr; if (arg_is_generic) assert(is_generic); - ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); + ZigValue **inner_fields = alloc_const_vals_ptrs(g, 3); inner_fields[0]->special = ConstValSpecialStatic; - inner_fields[0]->type = ira->codegen->builtin_types.entry_bool; + inner_fields[0]->type = g->builtin_types.entry_bool; inner_fields[0]->data.x_bool = arg_is_generic; inner_fields[1]->special = ConstValSpecialStatic; - inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; + inner_fields[1]->type = g->builtin_types.entry_bool; inner_fields[1]->data.x_bool = fn_param_info->is_noalias; inner_fields[2]->special = ConstValSpecialStatic; - inner_fields[2]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + inner_fields[2]->type = get_optional_type(g, g->builtin_types.entry_type); if (arg_is_generic) inner_fields[2]->data.x_optional = nullptr; else { - ZigValue *arg_type = ira->codegen->pass1_arena->create(); + ZigValue *arg_type = g->pass1_arena->create(); arg_type->special = ConstValSpecialStatic; - arg_type->type = ira->codegen->builtin_types.entry_type; + arg_type->type = g->builtin_types.entry_type; arg_type->data.x_type = fn_param_info->type; inner_fields[2]->data.x_optional = arg_type; } @@ -18733,11 +18736,11 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour } case ZigTypeIdOpaque: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Opaque", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); + ZigValue **fields = alloc_const_vals_ptrs(g, 1); result->data.x_struct.fields = fields; // decls: []TypeInfo.Declaration @@ -18752,21 +18755,24 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour } case ZigTypeIdFnFrame: { - result = ira->codegen->pass1_arena->create(); + result = g->pass1_arena->create(); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Frame", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); + ZigValue **fields = alloc_const_vals_ptrs(g, 1); result->data.x_struct.fields = fields; ZigFn *fn = type_entry->data.frame.fn; - // function: anytype + // function: ?*const anyopaque ensure_field_index(result->type, "function", 0); - fields[0] = create_const_fn(ira->codegen, fn); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = get_pointer_to_type(g, g->builtin_types.entry_anyopaque, true); + fields[0]->data.x_ptr.special = ConstPtrSpecialFunction; + fields[0]->data.x_ptr.data.fn.fn_entry = fn; break; } } assert(result != nullptr); - ira->codegen->type_info_cache.put(type_entry, result); + g->type_info_cache.put(type_entry, result); *out = result; return ErrorNone; } @@ -18810,26 +18816,25 @@ static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue return val; } -static Error get_const_field_sentinel(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigValue *struct_value, - const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) +static Error get_const_field_sentinel(IrAnalyze *ira, Scope *scope, AstNode *source_node, + ZigValue *struct_value, const char *name, size_t field_index, ZigType *elem_type, + ZigValue **result) { ZigValue *field_val = get_const_field(ira, source_node, struct_value, name, field_index); if (field_val == nullptr) return ErrorSemanticAnalyzeFail; - Stage1AirInst *field_inst = ir_const_move(ira, scope, source_node, field_val); - Stage1AirInst *casted_field_inst = ir_implicit_cast(ira, field_inst, - get_optional_type(ira->codegen, elem_type)); - if (type_is_invalid(casted_field_inst->value->type)) - return ErrorSemanticAnalyzeFail; - - if (optional_value_is_null(casted_field_inst->value)) { + // type of `field_val` is `?*const anyopaque`. + if (field_val->data.x_ptr.special == ConstPtrSpecialNull) { *result = nullptr; - } else { - assert(type_has_optional_repr(casted_field_inst->value->type)); - *result = casted_field_inst->value->data.x_optional; + return ErrorNone; } + ZigValue *pointee = const_ptr_pointee_unchecked_no_isf(ira->codegen, field_val); + if (pointee == nullptr) + return ErrorSemanticAnalyzeFail; + + *result = pointee; return ErrorNone; } @@ -19140,15 +19145,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ return get_any_frame_type(ira->codegen, child_type); } case ZigTypeIdFnFrame: { - assert(payload->special == ConstValSpecialStatic); - assert(payload->type == ir_type_info_get_type(ira, "Frame", nullptr)); - ZigValue *function = get_const_field(ira, source_node, payload, "function", 0); - if (function == nullptr) - return ira->codegen->invalid_inst_gen->value->type; - - assert(function->type->id == ZigTypeIdFn); - ZigFn *fn = function->data.x_ptr.data.fn.fn_entry; - return get_fn_frame_type(ira->codegen, fn); + ir_add_error_node(ira, source_node, + buf_sprintf("use the @Frame builtin instead of @Type")); + return ira->codegen->invalid_inst_gen->value->type; } case ZigTypeIdErrorSet: { assert(payload->special == ConstValSpecialStatic); @@ -19276,19 +19275,17 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_ ZigValue *default_value = get_const_field(ira, source_node, field_value, "default_value", 2); if (default_value == nullptr) return ira->codegen->invalid_inst_gen->value->type; - if (default_value->type->id == ZigTypeIdNull) { + + // type of `default_value` is `?*const anyopaque`. + if (default_value->data.x_ptr.special == ConstPtrSpecialNull) { field->init_val = nullptr; - } else if (default_value->type->id == ZigTypeIdOptional && default_value->type->data.maybe.child_type == field->type_entry) { - field->init_val = default_value->data.x_optional; - } else if (default_value->type == field->type_entry) { - field->init_val = default_value; } else { - ir_add_error_node(ira, source_node, - buf_sprintf("default_value of field '%s' is of type '%s', expected '%s' or '?%s'", - buf_ptr(field->name), buf_ptr(&default_value->type->name), - buf_ptr(&field->type_entry->name), buf_ptr(&field->type_entry->name))); - return ira->codegen->invalid_inst_gen->value->type; + ZigValue *pointee = const_ptr_pointee_unchecked_no_isf(ira->codegen, default_value); + if (pointee == nullptr) + return ira->codegen->invalid_inst_gen->value->type; + field->init_val = pointee; } + if ((err = get_const_field_bool(ira, source_node, field_value, "is_comptime", 3, &field->is_comptime))) return ira->codegen->invalid_inst_gen->value->type; BigInt *alignment = get_const_field_lit_int(ira, source_node, field_value, "alignment", 4); diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 1f49f216ce..ad300dac4e 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -119,7 +119,7 @@ fn testNullTerminatedPtr() !void { try expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many); try expect(ptr_info.Pointer.is_const == false); try expect(ptr_info.Pointer.is_volatile == false); - try expect(ptr_info.Pointer.sentinel.? == 0); + try expect(@ptrCast(*const u8, ptr_info.Pointer.sentinel.?).* == 0); try expect(@typeInfo([:0]u8).Pointer.sentinel != null); } @@ -161,7 +161,7 @@ fn testArray() !void { const info = @typeInfo([10:0]u8); try expect(info.Array.len == 10); try expect(info.Array.child == u8); - try expect(info.Array.sentinel.? == @as(u8, 0)); + try expect(@ptrCast(*const u8, info.Array.sentinel.?).* == @as(u8, 0)); try expect(@sizeOf([10:0]u8) == info.Array.len + 1); } } @@ -271,8 +271,8 @@ fn testStruct() !void { const unpacked_struct_info = @typeInfo(TestUnpackedStruct); try expect(unpacked_struct_info.Struct.is_tuple == false); try expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32)); - try expect(unpacked_struct_info.Struct.fields[0].default_value.? == 4); - try expectEqualStrings("foobar", unpacked_struct_info.Struct.fields[1].default_value.?); + try expect(@ptrCast(*const u32, unpacked_struct_info.Struct.fields[0].default_value.?).* == 4); + try expectEqualStrings("foobar", @ptrCast(*const *const [6:0]u8, unpacked_struct_info.Struct.fields[1].default_value.?).*); const struct_info = @typeInfo(TestStruct); try expect(struct_info == .Struct); @@ -282,7 +282,7 @@ fn testStruct() !void { try expect(struct_info.Struct.fields[0].alignment == 2 * @alignOf(usize)); try expect(struct_info.Struct.fields[2].field_type == *TestStruct); try expect(struct_info.Struct.fields[2].default_value == null); - try expect(struct_info.Struct.fields[3].default_value.? == 4); + try expect(@ptrCast(*const u32, struct_info.Struct.fields[3].default_value.?).* == 4); try expect(struct_info.Struct.fields[3].alignment == 1); try expect(struct_info.Struct.decls.len == 2); try expect(struct_info.Struct.decls[0].is_pub); @@ -452,7 +452,7 @@ test "type info for async frames" { switch (@typeInfo(@Frame(add))) { .Frame => |frame| { - try expect(frame.function == add); + try expect(@ptrCast(@TypeOf(add), frame.function) == add); }, else => unreachable, } diff --git a/test/behavior/type_stage1.zig b/test/behavior/type_stage1.zig index 911e6963c9..852c9fc82d 100644 --- a/test/behavior/type_stage1.zig +++ b/test/behavior/type_stage1.zig @@ -37,7 +37,7 @@ test "Type.Array" { .Array = TypeInfo.Array{ .len = 2, .child = u32, - .sentinel = 0, + .sentinel = &@as(u32, 0), }, })); try testTypes(&[_]type{ [1]u8, [30]usize, [7]bool }); @@ -141,12 +141,6 @@ fn add(a: i32, b: i32) i32 { return a + b; } -test "Type.Frame" { - try testTypes(&[_]type{ - @Frame(add), - }); -} - test "Type.ErrorSet" { // error sets don't compare equal so just check if they compile _ = @Type(@typeInfo(error{})); @@ -160,10 +154,10 @@ test "Type.Struct" { try testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout); try testing.expectEqualSlices(u8, "x", infoA.fields[0].name); try testing.expectEqual(u8, infoA.fields[0].field_type); - try testing.expectEqual(@as(?u8, null), infoA.fields[0].default_value); + try testing.expectEqual(@as(?*const anyopaque, null), infoA.fields[0].default_value); try testing.expectEqualSlices(u8, "y", infoA.fields[1].name); try testing.expectEqual(u32, infoA.fields[1].field_type); - try testing.expectEqual(@as(?u32, null), infoA.fields[1].default_value); + try testing.expectEqual(@as(?*const anyopaque, null), infoA.fields[1].default_value); try testing.expectEqualSlices(TypeInfo.Declaration, &[_]TypeInfo.Declaration{}, infoA.decls); try testing.expectEqual(@as(bool, false), infoA.is_tuple); @@ -178,10 +172,10 @@ test "Type.Struct" { try testing.expectEqual(TypeInfo.ContainerLayout.Extern, infoB.layout); try testing.expectEqualSlices(u8, "x", infoB.fields[0].name); try testing.expectEqual(u8, infoB.fields[0].field_type); - try testing.expectEqual(@as(?u8, null), infoB.fields[0].default_value); + try testing.expectEqual(@as(?*const anyopaque, null), infoB.fields[0].default_value); try testing.expectEqualSlices(u8, "y", infoB.fields[1].name); try testing.expectEqual(u32, infoB.fields[1].field_type); - try testing.expectEqual(@as(?u32, 5), infoB.fields[1].default_value); + try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoB.fields[1].default_value.?).*); try testing.expectEqual(@as(usize, 0), infoB.decls.len); try testing.expectEqual(@as(bool, false), infoB.is_tuple); @@ -190,10 +184,10 @@ test "Type.Struct" { try testing.expectEqual(TypeInfo.ContainerLayout.Packed, infoC.layout); try testing.expectEqualSlices(u8, "x", infoC.fields[0].name); try testing.expectEqual(u8, infoC.fields[0].field_type); - try testing.expectEqual(@as(?u8, 3), infoC.fields[0].default_value); + try testing.expectEqual(@as(u8, 3), @ptrCast(*const u8, infoC.fields[0].default_value.?).*); try testing.expectEqualSlices(u8, "y", infoC.fields[1].name); try testing.expectEqual(u32, infoC.fields[1].field_type); - try testing.expectEqual(@as(?u32, 5), infoC.fields[1].default_value); + try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoC.fields[1].default_value.?).*); try testing.expectEqual(@as(usize, 0), infoC.decls.len); try testing.expectEqual(@as(bool, false), infoC.is_tuple); } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 9f32b9e1c3..88a596a880 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -744,7 +744,7 @@ pub fn addCases(ctx: *TestContext) !void { \\ .address_space = .generic, \\ .child = u8, \\ .is_allowzero = false, - \\ .sentinel = 0, + \\ .sentinel = &@as(u8, 0), \\ }}); \\} , &[_][]const u8{