Skip to content

Commit d3693dc

Browse files
committed
Pointer Reform: update @typeinfo
* add assertion for trying to do @typeinfo on global error set * remove TypeInfo.Slice * add TypeInfo.Pointer.Size with possible values - One - Many - Slice See #770
1 parent 76c8efd commit d3693dc

File tree

5 files changed

+102
-55
lines changed

5 files changed

+102
-55
lines changed

src/analyze.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5981,7 +5981,7 @@ size_t type_id_index(TypeTableEntry *entry) {
59815981
return 7;
59825982
case TypeTableEntryIdStruct:
59835983
if (entry->data.structure.is_slice)
5984-
return 25;
5984+
return 6;
59855985
return 8;
59865986
case TypeTableEntryIdComptimeFloat:
59875987
return 9;

src/codegen.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6481,7 +6481,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
64816481
const TypeTableEntryId id = type_id_at_index(i);
64826482
buf_appendf(contents, " %s,\n", type_id_name(id));
64836483
}
6484-
buf_appendf(contents, " Slice,\n");
64856484
buf_appendf(contents, "};\n\n");
64866485
}
64876486
{
@@ -6494,7 +6493,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
64946493
" Int: Int,\n"
64956494
" Float: Float,\n"
64966495
" Pointer: Pointer,\n"
6497-
" Slice: Slice,\n"
64986496
" Array: Array,\n"
64996497
" Struct: Struct,\n"
65006498
" ComptimeFloat: void,\n"
@@ -6524,13 +6522,18 @@ static void define_builtin_compile_vars(CodeGen *g) {
65246522
" };\n"
65256523
"\n"
65266524
" pub const Pointer = struct {\n"
6525+
" size: Size,\n"
65276526
" is_const: bool,\n"
65286527
" is_volatile: bool,\n"
65296528
" alignment: u32,\n"
65306529
" child: type,\n"
6531-
" };\n"
65326530
"\n"
6533-
" pub const Slice = Pointer;\n"
6531+
" pub const Size = enum {\n"
6532+
" One,\n"
6533+
" Many,\n"
6534+
" Slice,\n"
6535+
" };\n"
6536+
" };\n"
65346537
"\n"
65356538
" pub const Array = struct {\n"
65366539
" len: usize,\n"

src/ir.cpp

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16222,8 +16222,7 @@ static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop
1622216222
return true;
1622316223
}
1622416224

16225-
static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry)
16226-
{
16225+
static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) {
1622716226
assert(type_entry != nullptr);
1622816227
assert(!type_is_invalid(type_entry));
1622916228

@@ -16248,38 +16247,67 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
1624816247
enum_field_val->data.x_struct.fields = inner_fields;
1624916248
};
1625016249

16251-
const auto create_ptr_like_type_info = [ira](const char *name, TypeTableEntry *ptr_type_entry) {
16250+
const auto create_ptr_like_type_info = [ira](TypeTableEntry *ptr_type_entry) {
16251+
TypeTableEntry *attrs_type;
16252+
uint32_t size_enum_index;
16253+
if (is_slice(ptr_type_entry)) {
16254+
attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry;
16255+
size_enum_index = 2;
16256+
} else if (ptr_type_entry->id == TypeTableEntryIdPointer) {
16257+
attrs_type = ptr_type_entry;
16258+
size_enum_index = (ptr_type_entry->data.pointer.ptr_len == PtrLenSingle) ? 0 : 1;
16259+
} else {
16260+
zig_unreachable();
16261+
}
16262+
16263+
TypeTableEntry *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer");
16264+
ensure_complete_type(ira->codegen, type_info_pointer_type);
16265+
assert(!type_is_invalid(type_info_pointer_type));
16266+
1625216267
ConstExprValue *result = create_const_vals(1);
1625316268
result->special = ConstValSpecialStatic;
16254-
result->type = ir_type_info_get_type(ira, name);
16269+
result->type = type_info_pointer_type;
1625516270

16256-
ConstExprValue *fields = create_const_vals(4);
16271+
ConstExprValue *fields = create_const_vals(5);
1625716272
result->data.x_struct.fields = fields;
1625816273

16259-
// is_const: bool
16260-
ensure_field_index(result->type, "is_const", 0);
16274+
// size: Size
16275+
ensure_field_index(result->type, "size", 0);
16276+
TypeTableEntry *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type);
16277+
ensure_complete_type(ira->codegen, type_info_pointer_size_type);
16278+
assert(!type_is_invalid(type_info_pointer_size_type));
1626116279
fields[0].special = ConstValSpecialStatic;
16262-
fields[0].type = ira->codegen->builtin_types.entry_bool;
16263-
fields[0].data.x_bool = ptr_type_entry->data.pointer.is_const;
16264-
// is_volatile: bool
16265-
ensure_field_index(result->type, "is_volatile", 1);
16280+
fields[0].type = type_info_pointer_size_type;
16281+
bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index);
16282+
16283+
// is_const: bool
16284+
ensure_field_index(result->type, "is_const", 1);
1626616285
fields[1].special = ConstValSpecialStatic;
1626716286
fields[1].type = ira->codegen->builtin_types.entry_bool;
16268-
fields[1].data.x_bool = ptr_type_entry->data.pointer.is_volatile;
16269-
// alignment: u32
16270-
ensure_field_index(result->type, "alignment", 2);
16287+
fields[1].data.x_bool = attrs_type->data.pointer.is_const;
16288+
// is_volatile: bool
16289+
ensure_field_index(result->type, "is_volatile", 2);
1627116290
fields[2].special = ConstValSpecialStatic;
16272-
fields[2].type = ira->codegen->builtin_types.entry_u32;
16273-
bigint_init_unsigned(&fields[2].data.x_bigint, ptr_type_entry->data.pointer.alignment);
16274-
// child: type
16275-
ensure_field_index(result->type, "child", 3);
16291+
fields[2].type = ira->codegen->builtin_types.entry_bool;
16292+
fields[2].data.x_bool = attrs_type->data.pointer.is_volatile;
16293+
// alignment: u32
16294+
ensure_field_index(result->type, "alignment", 3);
1627616295
fields[3].special = ConstValSpecialStatic;
16277-
fields[3].type = ira->codegen->builtin_types.entry_type;
16278-
fields[3].data.x_type = ptr_type_entry->data.pointer.child_type;
16296+
fields[3].type = ira->codegen->builtin_types.entry_u32;
16297+
bigint_init_unsigned(&fields[3].data.x_bigint, attrs_type->data.pointer.alignment);
16298+
// child: type
16299+
ensure_field_index(result->type, "child", 4);
16300+
fields[4].special = ConstValSpecialStatic;
16301+
fields[4].type = ira->codegen->builtin_types.entry_type;
16302+
fields[4].data.x_type = attrs_type->data.pointer.child_type;
1627916303

1628016304
return result;
1628116305
};
1628216306

16307+
if (type_entry == ira->codegen->builtin_types.entry_global_error_set) {
16308+
zig_panic("TODO implement @typeInfo for global error set");
16309+
}
16310+
1628316311
ConstExprValue *result = nullptr;
1628416312
switch (type_entry->id)
1628516313
{
@@ -16348,7 +16376,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
1634816376
}
1634916377
case TypeTableEntryIdPointer:
1635016378
{
16351-
result = create_ptr_like_type_info("Pointer", type_entry);
16379+
result = create_ptr_like_type_info(type_entry);
1635216380
break;
1635316381
}
1635416382
case TypeTableEntryIdArray:
@@ -16621,15 +16649,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
1662116649
case TypeTableEntryIdStruct:
1662216650
{
1662316651
if (type_entry->data.structure.is_slice) {
16624-
Buf ptr_field_name = BUF_INIT;
16625-
buf_init_from_str(&ptr_field_name, "ptr");
16626-
TypeTableEntry *ptr_type = type_entry->data.structure.fields_by_name.get(&ptr_field_name)->type_entry;
16627-
ensure_complete_type(ira->codegen, ptr_type);
16628-
if (type_is_invalid(ptr_type))
16629-
return nullptr;
16630-
buf_deinit(&ptr_field_name);
16631-
16632-
result = create_ptr_like_type_info("Slice", ptr_type);
16652+
result = create_ptr_like_type_info(type_entry);
1663316653
break;
1663416654
}
1663516655

std/fmt/index.zig

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@ pub fn formatType(
9797
output: fn (@typeOf(context), []const u8) Errors!void,
9898
) Errors!void {
9999
const T = @typeOf(value);
100-
switch (@typeId(T)) {
100+
if (T == error) {
101+
try output(context, "error.");
102+
return output(context, @errorName(value));
103+
}
104+
switch (@typeInfo(T)) {
101105
builtin.TypeId.Int, builtin.TypeId.Float => {
102106
return formatValue(value, fmt, context, Errors, output);
103107
},
@@ -125,12 +129,13 @@ pub fn formatType(
125129
try output(context, "error.");
126130
return output(context, @errorName(value));
127131
},
128-
builtin.TypeId.Pointer => {
129-
switch (@typeId(T.Child)) {
130-
builtin.TypeId.Array => {
131-
if (T.Child.Child == u8) {
132+
builtin.TypeId.Pointer => |ptr_info| switch (ptr_info.size) {
133+
builtin.TypeInfo.Pointer.Size.One => switch (@typeInfo(ptr_info.child)) {
134+
builtin.TypeId.Array => |info| {
135+
if (info.child == u8) {
132136
return formatText(value, fmt, context, Errors, output);
133137
}
138+
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
134139
},
135140
builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
136141
const has_cust_fmt = comptime cf: {
@@ -154,14 +159,16 @@ pub fn formatType(
154159
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
155160
},
156161
else => return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)),
157-
}
158-
},
159-
else => if (@canImplicitCast([]const u8, value)) {
160-
const casted_value = ([]const u8)(value);
161-
return output(context, casted_value);
162-
} else {
163-
@compileError("Unable to format type '" ++ @typeName(T) ++ "'");
162+
},
163+
builtin.TypeInfo.Pointer.Size.Many => {
164+
return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
165+
},
166+
builtin.TypeInfo.Pointer.Size.Slice => {
167+
const casted_value = ([]const u8)(value);
168+
return output(context, casted_value);
169+
},
164170
},
171+
else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
165172
}
166173
}
167174

test/cases/type_info.zig

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,41 @@ test "type info: pointer type info" {
3939
fn testPointer() void {
4040
const u32_ptr_info = @typeInfo(*u32);
4141
assert(TypeId(u32_ptr_info) == TypeId.Pointer);
42+
assert(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);
4243
assert(u32_ptr_info.Pointer.is_const == false);
4344
assert(u32_ptr_info.Pointer.is_volatile == false);
44-
assert(u32_ptr_info.Pointer.alignment == 4);
45+
assert(u32_ptr_info.Pointer.alignment == @alignOf(u32));
4546
assert(u32_ptr_info.Pointer.child == u32);
4647
}
4748

49+
test "type info: unknown length pointer type info" {
50+
testUnknownLenPtr();
51+
comptime testUnknownLenPtr();
52+
}
53+
54+
fn testUnknownLenPtr() void {
55+
const u32_ptr_info = @typeInfo([*]const volatile f64);
56+
assert(TypeId(u32_ptr_info) == TypeId.Pointer);
57+
assert(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);
58+
assert(u32_ptr_info.Pointer.is_const == true);
59+
assert(u32_ptr_info.Pointer.is_volatile == true);
60+
assert(u32_ptr_info.Pointer.alignment == @alignOf(f64));
61+
assert(u32_ptr_info.Pointer.child == f64);
62+
}
63+
4864
test "type info: slice type info" {
4965
testSlice();
5066
comptime testSlice();
5167
}
5268

5369
fn testSlice() void {
5470
const u32_slice_info = @typeInfo([]u32);
55-
assert(TypeId(u32_slice_info) == TypeId.Slice);
56-
assert(u32_slice_info.Slice.is_const == false);
57-
assert(u32_slice_info.Slice.is_volatile == false);
58-
assert(u32_slice_info.Slice.alignment == 4);
59-
assert(u32_slice_info.Slice.child == u32);
71+
assert(TypeId(u32_slice_info) == TypeId.Pointer);
72+
assert(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);
73+
assert(u32_slice_info.Pointer.is_const == false);
74+
assert(u32_slice_info.Pointer.is_volatile == false);
75+
assert(u32_slice_info.Pointer.alignment == 4);
76+
assert(u32_slice_info.Pointer.child == u32);
6077
}
6178

6279
test "type info: array type info" {
@@ -149,11 +166,11 @@ fn testUnion() void {
149166
assert(TypeId(typeinfo_info) == TypeId.Union);
150167
assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
151168
assert(typeinfo_info.Union.tag_type == TypeId);
152-
assert(typeinfo_info.Union.fields.len == 26);
169+
assert(typeinfo_info.Union.fields.len == 25);
153170
assert(typeinfo_info.Union.fields[4].enum_field != null);
154171
assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);
155172
assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
156-
assert(typeinfo_info.Union.defs.len == 21);
173+
assert(typeinfo_info.Union.defs.len == 20);
157174

158175
const TestNoTagUnion = union {
159176
Foo: void,

0 commit comments

Comments
 (0)