stage1: avoid anytype fields for type info

prerequisite for #10705
This commit is contained in:
Andrew Kelley 2022-02-01 18:10:19 -07:00
parent 5cf918143c
commit f4a249325e
10 changed files with 246 additions and 223 deletions

View file

@ -226,11 +226,10 @@ pub const TypeInfo = union(enum) {
child: type, child: type,
is_allowzero: bool, is_allowzero: bool,
/// This field is an optional type.
/// The type of the sentinel is the element type of the pointer, which is /// 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 /// the value of the `child` field in this struct. However there is no way
/// to refer to that type here, so we use `anytype`. /// to refer to that type here, so we use pointer to `anyopaque`.
sentinel: anytype, sentinel: ?*const anyopaque,
/// This data structure is used by the Zig language code generation and /// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation. /// therefore must be kept in sync with the compiler implementation.
@ -248,11 +247,10 @@ pub const TypeInfo = union(enum) {
len: comptime_int, len: comptime_int,
child: type, child: type,
/// This field is an optional type.
/// The type of the sentinel is the element type of the array, which is /// 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 /// the value of the `child` field in this struct. However there is no way
/// to refer to that type here, so we use `anytype`. /// to refer to that type here, so we use pointer to `anyopaque`.
sentinel: anytype, sentinel: ?*const anyopaque,
}; };
/// This data structure is used by the Zig language code generation and /// 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. /// therefore must be kept in sync with the compiler implementation.
pub const StructField = struct { pub const StructField = struct {
name: []const u8, name: []const u8,
/// TODO rename to `type`
field_type: type, field_type: type,
default_value: anytype, default_value: ?*const anyopaque,
is_comptime: bool, is_comptime: bool,
alignment: comptime_int, alignment: comptime_int,
}; };
@ -369,7 +368,7 @@ pub const TypeInfo = union(enum) {
/// This data structure is used by the Zig language code generation and /// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation. /// therefore must be kept in sync with the compiler implementation.
pub const Frame = struct { pub const Frame = struct {
function: anytype, function: *const anyopaque,
}; };
/// This data structure is used by the Zig language code generation and /// This data structure is used by the Zig language code generation and

View file

@ -16,7 +16,7 @@ pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_def
fields = fields ++ &[_]StructField{.{ fields = fields ++ &[_]StructField{.{
.name = field.name, .name = field.name,
.field_type = Data, .field_type = Data,
.default_value = field_default, .default_value = if (field_default) |d| &d else null,
.is_comptime = false, .is_comptime = false,
.alignment = if (@sizeOf(Data) > 0) @alignOf(Data) else 0, .alignment = if (@sizeOf(Data) > 0) @alignOf(Data) else 0,
}}; }};

View file

@ -296,7 +296,8 @@ pub fn zeroes(comptime T: type) T {
} }
}, },
.Array => |info| { .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 [_:sentinel]info.child{zeroes(info.child)} ** info.len;
} }
return [_]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); @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; @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"), else => @compileError("invalid type given to std.mem.Span"),
}, },
.C => { .C => {
new_ptr_info.sentinel = 0; new_ptr_info.sentinel = &@as(ptr_info.child, 0);
new_ptr_info.is_allowzero = false; new_ptr_info.is_allowzero = false;
}, },
.Many, .Slice => {}, .Many, .Slice => {},
@ -651,7 +653,9 @@ pub fn span(ptr: anytype) Span(@TypeOf(ptr)) {
} }
const Result = Span(@TypeOf(ptr)); const Result = Span(@TypeOf(ptr));
const l = len(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]; return ptr[0..l :s];
} else { } else {
return ptr[0..l]; 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 // 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 // to find the value searched for, which is only the case if it matches
// the sentinel of the type passed. // 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) { if (end == sentinel) {
new_ptr_info.sentinel = end; new_ptr_info.sentinel = &end;
} else { } else {
new_ptr_info.sentinel = null; 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 // 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 // to find the value searched for, which is only the case if it matches
// the sentinel of the type passed. // 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) { if (end == sentinel) {
new_ptr_info.sentinel = end; new_ptr_info.sentinel = &end;
} else { } else {
new_ptr_info.sentinel = null; new_ptr_info.sentinel = null;
} }
} }
}, },
.C => { .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. // C pointers are always allowzero, but we don't want the return type to be.
assert(new_ptr_info.is_allowzero); assert(new_ptr_info.is_allowzero);
new_ptr_info.is_allowzero = false; 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 Result = SliceTo(@TypeOf(ptr), end);
const length = lenSliceTo(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]; return ptr[0..length :s];
} else { } else {
return ptr[0..length]; 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) { .Pointer => |ptr_info| switch (ptr_info.size) {
.One => switch (@typeInfo(ptr_info.child)) { .One => switch (@typeInfo(ptr_info.child)) {
.Array => |array_info| { .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) { if (sentinel == end) {
return indexOfSentinel(array_info.child, end, ptr); return indexOfSentinel(array_info.child, end, ptr);
} }
@ -795,7 +804,8 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize {
}, },
else => {}, 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, // We may be looking for something other than the sentinel,
// but iterating past the sentinel would be a bug so we need // but iterating past the sentinel would be a bug so we need
// to check for both. // 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); return indexOfSentinel(ptr_info.child, end, ptr);
}, },
.Slice => { .Slice => {
if (ptr_info.sentinel) |sentinel| { if (ptr_info.sentinel) |sentinel_ptr| {
const sentinel = @ptrCast(*const ptr_info.child, sentinel_ptr).*;
if (sentinel == end) { if (sentinel == end) {
return indexOfSentinel(ptr_info.child, sentinel, ptr); return indexOfSentinel(ptr_info.child, sentinel, ptr);
} }
@ -867,10 +878,12 @@ pub fn len(value: anytype) usize {
.Array => value.len, .Array => value.len,
else => @compileError("invalid type given to std.mem.len"), else => @compileError("invalid type given to std.mem.len"),
}, },
.Many => if (info.sentinel) |sentinel| .Many => {
indexOfSentinel(info.child, sentinel, value) const sentinel_ptr = info.sentinel orelse
else @compileError("length of pointer with no sentinel");
@compileError("length of pointer with no sentinel"), const sentinel = @ptrCast(*const info.child, sentinel_ptr).*;
return indexOfSentinel(info.child, sentinel, value);
},
.C => { .C => {
assert(value != null); assert(value != null);
return indexOfSentinel(info.child, 0, value); return indexOfSentinel(info.child, 0, value);
@ -2572,7 +2585,11 @@ test "alignPointer" {
try S.checkAlign([*]u32, math.maxInt(usize) - 3, 8, 0); 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; const info = @typeInfo(source).Pointer;
return @Type(.{ return @Type(.{
.Pointer = .{ .Pointer = .{

View file

@ -190,12 +190,21 @@ test "std.meta.Elem" {
/// Types which cannot possibly have a sentinel will be a compile error. /// Types which cannot possibly have a sentinel will be a compile error.
pub fn sentinel(comptime T: type) ?Elem(T) { pub fn sentinel(comptime T: type) ?Elem(T) {
switch (@typeInfo(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| { .Pointer => |info| {
switch (info.size) { 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)) { .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 => {},
}, },
else => {}, else => {},
@ -239,7 +248,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
.Array = .{ .Array = .{
.len = array_info.len, .len = array_info.len,
.child = array_info.child, .child = array_info.child,
.sentinel = sentinel_val, .sentinel = &sentinel_val,
}, },
}), }),
.is_allowzero = info.is_allowzero, .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, .address_space = info.address_space,
.child = info.child, .child = info.child,
.is_allowzero = info.is_allowzero, .is_allowzero = info.is_allowzero,
.sentinel = sentinel_val, .sentinel = &sentinel_val,
}, },
}), }),
else => {}, else => {},
@ -275,7 +284,7 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
.address_space = ptr_info.address_space, .address_space = ptr_info.address_space,
.child = ptr_info.child, .child = ptr_info.child,
.is_allowzero = ptr_info.is_allowzero, .is_allowzero = ptr_info.is_allowzero,
.sentinel = sentinel_val, .sentinel = &sentinel_val,
}, },
}), }),
}, },

View file

@ -2108,6 +2108,7 @@ struct CodeGen {
ZigType *entry_global_error_set; ZigType *entry_global_error_set;
ZigType *entry_enum_literal; ZigType *entry_enum_literal;
ZigType *entry_any_frame; ZigType *entry_any_frame;
ZigType *entry_opt_ptr_const_anyopaque;
} builtin_types; } builtin_types;
struct Intern { struct Intern {

View file

@ -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); 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); ZigType *entry = new_type_table_entry(ZigTypeIdErrorSet);
buf_init_from_str(&entry->name, "anyerror"); buf_init_from_str(&entry->name, "anyerror");

View file

@ -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) { 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; ZigType *attrs_type;
BuiltinPtrSize size_enum_index; BuiltinPtrSize size_enum_index;
if (is_slice(ptr_type_entry)) { if (is_slice(ptr_type_entry)) {
TypeStructField *ptr_field = ptr_type_entry->data.structure.fields[slice_ptr_index]; 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; size_enum_index = BuiltinPtrSizeSlice;
} else if (ptr_type_entry->id == ZigTypeIdPointer) { } else if (ptr_type_entry->id == ZigTypeIdPointer) {
attrs_type = ptr_type_entry; 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); 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>(); ZigValue *result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = type_info_pointer_type; 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; result->data.x_struct.fields = fields;
// size: Size // size: Size
ensure_field_index(result->type, "size", 0); ensure_field_index(result->type, "size", 0);
ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 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]->special = ConstValSpecialStatic;
fields[0]->type = type_info_pointer_size_type; fields[0]->type = type_info_pointer_size_type;
bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index); 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 // is_const: bool
ensure_field_index(result->type, "is_const", 1); ensure_field_index(result->type, "is_const", 1);
fields[1]->special = ConstValSpecialStatic; 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; fields[1]->data.x_bool = attrs_type->data.pointer.is_const;
// is_volatile: bool // is_volatile: bool
ensure_field_index(result->type, "is_volatile", 2); ensure_field_index(result->type, "is_volatile", 2);
fields[2]->special = ConstValSpecialStatic; 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; fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile;
// alignment: comptime_int // alignment: comptime_int
ensure_field_index(result->type, "alignment", 3); 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) { if (attrs_type->data.pointer.explicit_alignment != 0) {
fields[3]->special = ConstValSpecialStatic; fields[3]->special = ConstValSpecialStatic;
bigint_init_unsigned(&fields[3]->data.x_bigint, attrs_type->data.pointer.explicit_alignment); 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, // address_space: AddressSpace,
ensure_field_index(result->type, "address_space", 4); ensure_field_index(result->type, "address_space", 4);
fields[4]->special = ConstValSpecialStatic; 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); bigint_init_unsigned(&fields[4]->data.x_enum_tag, AddressSpaceGeneric);
// child: type // child: type
ensure_field_index(result->type, "child", 5); ensure_field_index(result->type, "child", 5);
fields[5]->special = ConstValSpecialStatic; 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; fields[5]->data.x_type = attrs_type->data.pointer.child_type;
// is_allowzero: bool // is_allowzero: bool
ensure_field_index(result->type, "is_allowzero", 6); ensure_field_index(result->type, "is_allowzero", 6);
fields[6]->special = ConstValSpecialStatic; 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; fields[6]->data.x_bool = attrs_type->data.pointer.allow_zero;
// sentinel: anytype // sentinel: ?*const anyopaque
ensure_field_index(result->type, "sentinel", 7); ensure_field_index(result->type, "sentinel", 7);
fields[7]->special = ConstValSpecialStatic; fields[7]->special = ConstValSpecialStatic;
if (attrs_type->data.pointer.sentinel != nullptr) { fields[7]->type = g->builtin_types.entry_opt_ptr_const_anyopaque;
fields[7]->type = get_optional_type(ira->codegen, attrs_type->data.pointer.child_type); ZigValue *ptr_to_sent = (attrs_type->data.pointer.sentinel == nullptr) ? nullptr :
set_optional_payload(fields[7], attrs_type->data.pointer.sentinel); create_const_ptr_ref(g, attrs_type->data.pointer.sentinel, true);
} else { set_optional_payload(fields[7], ptr_to_sent);
fields[7]->type = ira->codegen->builtin_types.entry_null;
}
return result; 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_entry != nullptr);
assert(!type_is_invalid(type_entry)); 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) { if (entry != nullptr) {
*out = entry->value; *out = entry->value;
return ErrorNone; return ErrorNone;
@ -18172,43 +18173,43 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
case ZigTypeIdEnumLiteral: case ZigTypeIdEnumLiteral:
case ZigTypeIdUndefined: case ZigTypeIdUndefined:
case ZigTypeIdNull: case ZigTypeIdNull:
result = ira->codegen->intern.for_void(); result = g->intern.for_void();
break; break;
case ZigTypeIdInt: case ZigTypeIdInt:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Int", nullptr); 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; result->data.x_struct.fields = fields;
// is_signed: Signedness // is_signed: Signedness
ensure_field_index(result->type, "signedness", 0); ensure_field_index(result->type, "signedness", 0);
fields[0]->special = ConstValSpecialStatic; 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); bigint_init_unsigned(&fields[0]->data.x_enum_tag, !type_entry->data.integral.is_signed);
// bits: u8 // bits: u8
ensure_field_index(result->type, "bits", 1); ensure_field_index(result->type, "bits", 1);
fields[1]->special = ConstValSpecialStatic; 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); bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count);
break; break;
} }
case ZigTypeIdFloat: case ZigTypeIdFloat:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Float", nullptr); 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; result->data.x_struct.fields = fields;
// bits: u8 // bits: u8
ensure_field_index(result->type, "bits", 0); ensure_field_index(result->type, "bits", 0);
fields[0]->special = ConstValSpecialStatic; 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); bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count);
break; break;
@ -18222,97 +18223,96 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
} }
case ZigTypeIdArray: case ZigTypeIdArray:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Array", nullptr); 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; result->data.x_struct.fields = fields;
// len: usize // len: usize
ensure_field_index(result->type, "len", 0); ensure_field_index(result->type, "len", 0);
fields[0]->special = ConstValSpecialStatic; 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); bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len);
// child: type // child: type
ensure_field_index(result->type, "child", 1); ensure_field_index(result->type, "child", 1);
fields[1]->special = ConstValSpecialStatic; 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; 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; fields[2]->special = ConstValSpecialStatic;
if (type_entry->data.array.child_type != nullptr) { fields[2]->type = g->builtin_types.entry_opt_ptr_const_anyopaque;
fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type); ZigValue *ptr_to_sent = (type_entry->data.array.sentinel == nullptr) ? nullptr :
set_optional_payload(fields[2], type_entry->data.array.sentinel); create_const_ptr_ref(g, type_entry->data.array.sentinel, true);
} else { set_optional_payload(fields[2], ptr_to_sent);
fields[2]->type = ira->codegen->builtin_types.entry_null;
}
break; break;
} }
case ZigTypeIdVector: { case ZigTypeIdVector: {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Vector", nullptr); 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; result->data.x_struct.fields = fields;
// len: usize // len: usize
ensure_field_index(result->type, "len", 0); ensure_field_index(result->type, "len", 0);
fields[0]->special = ConstValSpecialStatic; 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); bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len);
// child: type // child: type
ensure_field_index(result->type, "child", 1); ensure_field_index(result->type, "child", 1);
fields[1]->special = ConstValSpecialStatic; 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; fields[1]->data.x_type = type_entry->data.vector.elem_type;
break; break;
} }
case ZigTypeIdOptional: case ZigTypeIdOptional:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Optional", nullptr); 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; result->data.x_struct.fields = fields;
// child: type // child: type
ensure_field_index(result->type, "child", 0); ensure_field_index(result->type, "child", 0);
fields[0]->special = ConstValSpecialStatic; 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; fields[0]->data.x_type = type_entry->data.maybe.child_type;
break; break;
} }
case ZigTypeIdAnyFrame: { case ZigTypeIdAnyFrame: {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); 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; result->data.x_struct.fields = fields;
// child: ?type // child: ?type
ensure_field_index(result->type, "child", 0); ensure_field_index(result->type, "child", 0);
fields[0]->special = ConstValSpecialStatic; 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 : 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; break;
} }
case ZigTypeIdEnum: case ZigTypeIdEnum:
{ {
if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) if ((err = type_resolve(g, type_entry, ResolveStatusSizeKnown)))
return err; return err;
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Enum", nullptr); 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; result->data.x_struct.fields = fields;
// layout: ContainerLayout // layout: ContainerLayout
@ -18323,24 +18323,24 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
// tag_type: type // tag_type: type
ensure_field_index(result->type, "tag_type", 1); ensure_field_index(result->type, "tag_type", 1);
fields[1]->special = ConstValSpecialStatic; 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[1]->data.x_type = type_entry->data.enumeration.tag_int_type;
// fields: []TypeInfo.EnumField // fields: []TypeInfo.EnumField
ensure_field_index(result->type, "fields", 2); ensure_field_index(result->type, "fields", 2);
ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 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(); zig_unreachable();
} }
uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; uint32_t enum_field_count = type_entry->data.enumeration.src_field_count;
ZigValue *enum_field_array = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *enum_field_array = g->pass1_arena->create<ZigValue>();
enum_field_array->special = ConstValSpecialStatic; 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.special = ConstArraySpecialNone;
enum_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(enum_field_count); enum_field_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(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++) 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 // is_exhaustive: bool
ensure_field_index(result->type, "is_exhaustive", 4); ensure_field_index(result->type, "is_exhaustive", 4);
fields[4]->special = ConstValSpecialStatic; 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; fields[4]->data.x_bool = !type_entry->data.enumeration.non_exhaustive;
break; break;
} }
case ZigTypeIdErrorSet: case ZigTypeIdErrorSet:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr);
ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", 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; return ErrorSemanticAnalyzeFail;
} }
if (type_is_global_error_set(type_entry)) { if (type_is_global_error_set(type_entry)) {
result->data.x_optional = nullptr; result->data.x_optional = nullptr;
break; break;
} }
if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { if ((err = type_resolve(g, type_info_error_type, ResolveStatusSizeKnown))) {
zig_unreachable(); zig_unreachable();
} }
ZigValue *slice_val = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *slice_val = g->pass1_arena->create<ZigValue>();
result->data.x_optional = slice_val; result->data.x_optional = slice_val;
uint32_t error_count = type_entry->data.error_set.err_count; uint32_t error_count = type_entry->data.error_set.err_count;
ZigValue *error_array = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *error_array = g->pass1_arena->create<ZigValue>();
error_array->special = ConstValSpecialStatic; 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.special = ConstArraySpecialNone;
error_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(error_count); error_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(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++) { for (uint32_t error_index = 0; error_index < error_count; error_index++) {
ErrorTableEntry *error = type_entry->data.error_set.errors[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]; 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->special = ConstValSpecialStatic;
error_val->type = type_info_error_type; 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; ZigValue *name = nullptr;
if (error->cached_error_name_val != nullptr) if (error->cached_error_name_val != nullptr)
name = error->cached_error_name_val; name = error->cached_error_name_val;
if (name == nullptr) if (name == nullptr)
name = create_const_str_lit(ira->codegen, &error->name)->data.x_ptr.data.ref.pointee; name = create_const_str_lit(g, &error->name)->data.x_ptr.data.ref.pointee;
init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true, nullptr); 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->data.x_struct.fields = inner_fields;
error_val->parent.id = ConstParentIdArray; error_val->parent.id = ConstParentIdArray;
@ -18420,37 +18420,37 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
} }
case ZigTypeIdErrorUnion: case ZigTypeIdErrorUnion:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 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; result->data.x_struct.fields = fields;
// error_set: type // error_set: type
ensure_field_index(result->type, "error_set", 0); ensure_field_index(result->type, "error_set", 0);
fields[0]->special = ConstValSpecialStatic; 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; fields[0]->data.x_type = type_entry->data.error_union.err_set_type;
// payload: type // payload: type
ensure_field_index(result->type, "payload", 1); ensure_field_index(result->type, "payload", 1);
fields[1]->special = ConstValSpecialStatic; 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; fields[1]->data.x_type = type_entry->data.error_union.payload_type;
break; break;
} }
case ZigTypeIdUnion: case ZigTypeIdUnion:
{ {
if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) if ((err = type_resolve(g, type_entry, ResolveStatusSizeKnown)))
return err; return err;
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Union", nullptr); 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; result->data.x_struct.fields = fields;
// layout: ContainerLayout // layout: ContainerLayout
@ -18461,15 +18461,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
// tag_type: ?type // tag_type: ?type
ensure_field_index(result->type, "tag_type", 1); ensure_field_index(result->type, "tag_type", 1);
fields[1]->special = ConstValSpecialStatic; 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; AstNode *union_decl_node = type_entry->data.unionation.decl_node;
if (union_decl_node->data.container_decl.auto_enum || if (union_decl_node->data.container_decl.auto_enum ||
union_decl_node->data.container_decl.init_arg_expr != nullptr) union_decl_node->data.container_decl.init_arg_expr != nullptr)
{ {
ZigValue *tag_type = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *tag_type = g->pass1_arena->create<ZigValue>();
tag_type->special = ConstValSpecialStatic; 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; tag_type->data.x_type = type_entry->data.unionation.tag_type;
fields[1]->data.x_optional = tag_type; fields[1]->data.x_optional = tag_type;
} else { } 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); ensure_field_index(result->type, "fields", 2);
ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 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(); zig_unreachable();
uint32_t union_field_count = type_entry->data.unionation.src_field_count; uint32_t union_field_count = type_entry->data.unionation.src_field_count;
ZigValue *union_field_array = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *union_field_array = g->pass1_arena->create<ZigValue>();
union_field_array->special = ConstValSpecialStatic; 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.special = ConstArraySpecialNone;
union_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(union_field_count); union_field_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(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++) { 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]; 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->special = ConstValSpecialStatic;
union_field_val->type = type_info_union_field_type; 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 // field_type: type
inner_fields[1]->special = ConstValSpecialStatic; 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; inner_fields[1]->data.x_type = union_field->type_entry;
// alignment: comptime_int // alignment: comptime_int
inner_fields[2]->special = ConstValSpecialStatic; 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); 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; ZigValue *name = create_const_str_lit(g, 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); 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->data.x_struct.fields = inner_fields;
union_field_val->parent.id = ConstParentIdArray; union_field_val->parent.id = ConstParentIdArray;
@ -18536,14 +18536,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
break; break;
} }
if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) if ((err = type_resolve(g, type_entry, ResolveStatusSizeKnown)))
return err; return err;
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Struct", nullptr); 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; result->data.x_struct.fields = fields;
// layout: ContainerLayout // 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); ensure_field_index(result->type, "fields", 1);
ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 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(); zig_unreachable();
} }
uint32_t struct_field_count = type_entry->data.structure.src_field_count; uint32_t struct_field_count = type_entry->data.structure.src_field_count;
ZigValue *struct_field_array = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *struct_field_array = g->pass1_arena->create<ZigValue>();
struct_field_array->special = ConstValSpecialStatic; 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.special = ConstArraySpecialNone;
struct_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(struct_field_count); struct_field_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(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++) { 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]; 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->special = ConstValSpecialStatic;
struct_field_val->type = type_info_struct_field_type; 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]->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; 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]->special = ConstValSpecialStatic;
inner_fields[2]->type = get_optional_type2(ira->codegen, struct_field->type_entry); inner_fields[2]->type = g->builtin_types.entry_opt_ptr_const_anyopaque;
if (inner_fields[2]->type == nullptr) return ErrorSemanticAnalyzeFail; memoize_field_init_val(g, type_entry, struct_field);
memoize_field_init_val(ira->codegen, type_entry, struct_field); if (struct_field->init_val != nullptr &&
if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){ type_is_invalid(struct_field->init_val->type))
{
return ErrorSemanticAnalyzeFail; 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 // is_comptime: bool
inner_fields[3]->special = ConstValSpecialStatic; 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; inner_fields[3]->data.x_bool = struct_field->is_comptime;
// alignment: comptime_int // alignment: comptime_int
inner_fields[4]->special = ConstValSpecialStatic; 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); 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; ZigValue *name = create_const_str_lit(g, 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); 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->data.x_struct.fields = inner_fields;
struct_field_val->parent.id = ConstParentIdArray; 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 // is_tuple: bool
ensure_field_index(result->type, "is_tuple", 3); ensure_field_index(result->type, "is_tuple", 3);
fields[3]->special = ConstValSpecialStatic; 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); fields[3]->data.x_bool = is_tuple(type_entry);
break; break;
} }
case ZigTypeIdFn: case ZigTypeIdFn:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Fn", nullptr); 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; result->data.x_struct.fields = fields;
// calling_convention: TypeInfo.CallingConvention // calling_convention: TypeInfo.CallingConvention
ensure_field_index(result->type, "calling_convention", 0); ensure_field_index(result->type, "calling_convention", 0);
fields[0]->special = ConstValSpecialStatic; 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); bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);
// alignment: comptime_int // alignment: comptime_int
ensure_field_index(result->type, "alignment", 1); ensure_field_index(result->type, "alignment", 1);
fields[1]->special = ConstValSpecialStatic; 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, get_ptr_align(ira->codegen, type_entry)); bigint_init_unsigned(&fields[1]->data.x_bigint, get_ptr_align(g, type_entry));
// is_generic: bool // is_generic: bool
ensure_field_index(result->type, "is_generic", 2); ensure_field_index(result->type, "is_generic", 2);
bool is_generic = type_entry->data.fn.is_generic; bool is_generic = type_entry->data.fn.is_generic;
fields[2]->special = ConstValSpecialStatic; 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; fields[2]->data.x_bool = is_generic;
// is_varargs: bool // is_varargs: bool
ensure_field_index(result->type, "is_var_args", 3); ensure_field_index(result->type, "is_var_args", 3);
bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args;
fields[3]->special = ConstValSpecialStatic; 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; fields[3]->data.x_bool = is_varargs;
// return_type: ?type // return_type: ?type
ensure_field_index(result->type, "return_type", 4); ensure_field_index(result->type, "return_type", 4);
fields[4]->special = ConstValSpecialStatic; 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) if (type_entry->data.fn.fn_type_id.return_type == nullptr)
fields[4]->data.x_optional = nullptr; fields[4]->data.x_optional = nullptr;
else { else {
ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *return_type = g->pass1_arena->create<ZigValue>();
return_type->special = ConstValSpecialStatic; 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; return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
fields[4]->data.x_optional = return_type; fields[4]->data.x_optional = return_type;
} }
// args: []TypeInfo.FnArg // args: []TypeInfo.FnArg
ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 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(); zig_unreachable();
} }
size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count; size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count;
ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *fn_arg_array = g->pass1_arena->create<ZigValue>();
fn_arg_array->special = ConstValSpecialStatic; 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.special = ConstArraySpecialNone;
fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); fn_arg_array->data.x_array.data.s_none.elements = g->pass1_arena->allocate<ZigValue>(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++) { 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]; 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; bool arg_is_generic = fn_param_info->type == nullptr;
if (arg_is_generic) assert(is_generic); 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]->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[0]->data.x_bool = arg_is_generic;
inner_fields[1]->special = ConstValSpecialStatic; 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[1]->data.x_bool = fn_param_info->is_noalias;
inner_fields[2]->special = ConstValSpecialStatic; 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) if (arg_is_generic)
inner_fields[2]->data.x_optional = nullptr; inner_fields[2]->data.x_optional = nullptr;
else { else {
ZigValue *arg_type = ira->codegen->pass1_arena->create<ZigValue>(); ZigValue *arg_type = g->pass1_arena->create<ZigValue>();
arg_type->special = ConstValSpecialStatic; 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; arg_type->data.x_type = fn_param_info->type;
inner_fields[2]->data.x_optional = arg_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: case ZigTypeIdOpaque:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Opaque", nullptr); 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; result->data.x_struct.fields = fields;
// decls: []TypeInfo.Declaration // decls: []TypeInfo.Declaration
@ -18752,21 +18755,24 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
} }
case ZigTypeIdFnFrame: case ZigTypeIdFnFrame:
{ {
result = ira->codegen->pass1_arena->create<ZigValue>(); result = g->pass1_arena->create<ZigValue>();
result->special = ConstValSpecialStatic; result->special = ConstValSpecialStatic;
result->type = ir_type_info_get_type(ira, "Frame", nullptr); 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; result->data.x_struct.fields = fields;
ZigFn *fn = type_entry->data.frame.fn; ZigFn *fn = type_entry->data.frame.fn;
// function: anytype // function: ?*const anyopaque
ensure_field_index(result->type, "function", 0); 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; break;
} }
} }
assert(result != nullptr); assert(result != nullptr);
ira->codegen->type_info_cache.put(type_entry, result); g->type_info_cache.put(type_entry, result);
*out = result; *out = result;
return ErrorNone; return ErrorNone;
} }
@ -18810,26 +18816,25 @@ static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue
return val; return val;
} }
static Error get_const_field_sentinel(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigValue *struct_value, static Error get_const_field_sentinel(IrAnalyze *ira, Scope *scope, AstNode *source_node,
const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) 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); ZigValue *field_val = get_const_field(ira, source_node, struct_value, name, field_index);
if (field_val == nullptr) if (field_val == nullptr)
return ErrorSemanticAnalyzeFail; return ErrorSemanticAnalyzeFail;
Stage1AirInst *field_inst = ir_const_move(ira, scope, source_node, field_val); // type of `field_val` is `?*const anyopaque`.
Stage1AirInst *casted_field_inst = ir_implicit_cast(ira, field_inst, if (field_val->data.x_ptr.special == ConstPtrSpecialNull) {
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)) {
*result = nullptr; *result = nullptr;
} else { return ErrorNone;
assert(type_has_optional_repr(casted_field_inst->value->type));
*result = casted_field_inst->value->data.x_optional;
} }
ZigValue *pointee = const_ptr_pointee_unchecked_no_isf(ira->codegen, field_val);
if (pointee == nullptr)
return ErrorSemanticAnalyzeFail;
*result = pointee;
return ErrorNone; 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); return get_any_frame_type(ira->codegen, child_type);
} }
case ZigTypeIdFnFrame: { case ZigTypeIdFnFrame: {
assert(payload->special == ConstValSpecialStatic); ir_add_error_node(ira, source_node,
assert(payload->type == ir_type_info_get_type(ira, "Frame", nullptr)); buf_sprintf("use the @Frame builtin instead of @Type"));
ZigValue *function = get_const_field(ira, source_node, payload, "function", 0); return ira->codegen->invalid_inst_gen->value->type;
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);
} }
case ZigTypeIdErrorSet: { case ZigTypeIdErrorSet: {
assert(payload->special == ConstValSpecialStatic); 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); ZigValue *default_value = get_const_field(ira, source_node, field_value, "default_value", 2);
if (default_value == nullptr) if (default_value == nullptr)
return ira->codegen->invalid_inst_gen->value->type; 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; 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 { } else {
ir_add_error_node(ira, source_node, ZigValue *pointee = const_ptr_pointee_unchecked_no_isf(ira->codegen, default_value);
buf_sprintf("default_value of field '%s' is of type '%s', expected '%s' or '?%s'", if (pointee == nullptr)
buf_ptr(field->name), buf_ptr(&default_value->type->name), return ira->codegen->invalid_inst_gen->value->type;
buf_ptr(&field->type_entry->name), buf_ptr(&field->type_entry->name))); field->init_val = pointee;
return ira->codegen->invalid_inst_gen->value->type;
} }
if ((err = get_const_field_bool(ira, source_node, field_value, "is_comptime", 3, &field->is_comptime))) 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; return ira->codegen->invalid_inst_gen->value->type;
BigInt *alignment = get_const_field_lit_int(ira, source_node, field_value, "alignment", 4); BigInt *alignment = get_const_field_lit_int(ira, source_node, field_value, "alignment", 4);

View file

@ -119,7 +119,7 @@ fn testNullTerminatedPtr() !void {
try expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many); try expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);
try expect(ptr_info.Pointer.is_const == false); try expect(ptr_info.Pointer.is_const == false);
try expect(ptr_info.Pointer.is_volatile == 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); try expect(@typeInfo([:0]u8).Pointer.sentinel != null);
} }
@ -161,7 +161,7 @@ fn testArray() !void {
const info = @typeInfo([10:0]u8); const info = @typeInfo([10:0]u8);
try expect(info.Array.len == 10); try expect(info.Array.len == 10);
try expect(info.Array.child == u8); 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); try expect(@sizeOf([10:0]u8) == info.Array.len + 1);
} }
} }
@ -271,8 +271,8 @@ fn testStruct() !void {
const unpacked_struct_info = @typeInfo(TestUnpackedStruct); const unpacked_struct_info = @typeInfo(TestUnpackedStruct);
try expect(unpacked_struct_info.Struct.is_tuple == false); 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].alignment == @alignOf(u32));
try expect(unpacked_struct_info.Struct.fields[0].default_value.? == 4); try expect(@ptrCast(*const u32, unpacked_struct_info.Struct.fields[0].default_value.?).* == 4);
try expectEqualStrings("foobar", unpacked_struct_info.Struct.fields[1].default_value.?); try expectEqualStrings("foobar", @ptrCast(*const *const [6:0]u8, unpacked_struct_info.Struct.fields[1].default_value.?).*);
const struct_info = @typeInfo(TestStruct); const struct_info = @typeInfo(TestStruct);
try expect(struct_info == .Struct); 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[0].alignment == 2 * @alignOf(usize));
try expect(struct_info.Struct.fields[2].field_type == *TestStruct); 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[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.fields[3].alignment == 1);
try expect(struct_info.Struct.decls.len == 2); try expect(struct_info.Struct.decls.len == 2);
try expect(struct_info.Struct.decls[0].is_pub); try expect(struct_info.Struct.decls[0].is_pub);
@ -452,7 +452,7 @@ test "type info for async frames" {
switch (@typeInfo(@Frame(add))) { switch (@typeInfo(@Frame(add))) {
.Frame => |frame| { .Frame => |frame| {
try expect(frame.function == add); try expect(@ptrCast(@TypeOf(add), frame.function) == add);
}, },
else => unreachable, else => unreachable,
} }

View file

@ -37,7 +37,7 @@ test "Type.Array" {
.Array = TypeInfo.Array{ .Array = TypeInfo.Array{
.len = 2, .len = 2,
.child = u32, .child = u32,
.sentinel = 0, .sentinel = &@as(u32, 0),
}, },
})); }));
try testTypes(&[_]type{ [1]u8, [30]usize, [7]bool }); try testTypes(&[_]type{ [1]u8, [30]usize, [7]bool });
@ -141,12 +141,6 @@ fn add(a: i32, b: i32) i32 {
return a + b; return a + b;
} }
test "Type.Frame" {
try testTypes(&[_]type{
@Frame(add),
});
}
test "Type.ErrorSet" { test "Type.ErrorSet" {
// error sets don't compare equal so just check if they compile // error sets don't compare equal so just check if they compile
_ = @Type(@typeInfo(error{})); _ = @Type(@typeInfo(error{}));
@ -160,10 +154,10 @@ test "Type.Struct" {
try testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout); try testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout);
try testing.expectEqualSlices(u8, "x", infoA.fields[0].name); try testing.expectEqualSlices(u8, "x", infoA.fields[0].name);
try testing.expectEqual(u8, infoA.fields[0].field_type); 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.expectEqualSlices(u8, "y", infoA.fields[1].name);
try testing.expectEqual(u32, infoA.fields[1].field_type); 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.expectEqualSlices(TypeInfo.Declaration, &[_]TypeInfo.Declaration{}, infoA.decls);
try testing.expectEqual(@as(bool, false), infoA.is_tuple); 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.expectEqual(TypeInfo.ContainerLayout.Extern, infoB.layout);
try testing.expectEqualSlices(u8, "x", infoB.fields[0].name); try testing.expectEqualSlices(u8, "x", infoB.fields[0].name);
try testing.expectEqual(u8, infoB.fields[0].field_type); 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.expectEqualSlices(u8, "y", infoB.fields[1].name);
try testing.expectEqual(u32, infoB.fields[1].field_type); 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(usize, 0), infoB.decls.len);
try testing.expectEqual(@as(bool, false), infoB.is_tuple); 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.expectEqual(TypeInfo.ContainerLayout.Packed, infoC.layout);
try testing.expectEqualSlices(u8, "x", infoC.fields[0].name); try testing.expectEqualSlices(u8, "x", infoC.fields[0].name);
try testing.expectEqual(u8, infoC.fields[0].field_type); 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.expectEqualSlices(u8, "y", infoC.fields[1].name);
try testing.expectEqual(u32, infoC.fields[1].field_type); 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(usize, 0), infoC.decls.len);
try testing.expectEqual(@as(bool, false), infoC.is_tuple); try testing.expectEqual(@as(bool, false), infoC.is_tuple);
} }

View file

@ -744,7 +744,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ .address_space = .generic, \\ .address_space = .generic,
\\ .child = u8, \\ .child = u8,
\\ .is_allowzero = false, \\ .is_allowzero = false,
\\ .sentinel = 0, \\ .sentinel = &@as(u8, 0),
\\ }}); \\ }});
\\} \\}
, &[_][]const u8{ , &[_][]const u8{