authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-06 00:39:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-06 00:39:39-04:00
logd3693dca73dfc726aed32908691437abe614e5cf
tree167e2d8c24c6a653f05723716b796949a0eb5585
parent76c8efd56c84c189a52d3dc559fff109d5d34ce4

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

5 files changed, 102 insertions(+), 55 deletions(-)

src/analyze.cpp+1-1
...@@ -5981,7 +5981,7 @@ size_t type_id_index(TypeTableEntry *entry) {...@@ -5981,7 +5981,7 @@ size_t type_id_index(TypeTableEntry *entry) {
5981 return 7;5981 return 7;
5982 case TypeTableEntryIdStruct:5982 case TypeTableEntryIdStruct:
5983 if (entry->data.structure.is_slice)5983 if (entry->data.structure.is_slice)
5984 return 25;5984 return 6;
5985 return 8;5985 return 8;
5986 case TypeTableEntryIdComptimeFloat:5986 case TypeTableEntryIdComptimeFloat:
5987 return 9;5987 return 9;
src/codegen.cpp+7-4
...@@ -6481,7 +6481,6 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6481,7 +6481,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
6481 const TypeTableEntryId id = type_id_at_index(i);6481 const TypeTableEntryId id = type_id_at_index(i);
6482 buf_appendf(contents, " %s,\n", type_id_name(id));6482 buf_appendf(contents, " %s,\n", type_id_name(id));
6483 }6483 }
6484 buf_appendf(contents, " Slice,\n");
6485 buf_appendf(contents, "};\n\n");6484 buf_appendf(contents, "};\n\n");
6486 }6485 }
6487 {6486 {
...@@ -6494,7 +6493,6 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6494,7 +6493,6 @@ static void define_builtin_compile_vars(CodeGen *g) {
6494 " Int: Int,\n"6493 " Int: Int,\n"
6495 " Float: Float,\n"6494 " Float: Float,\n"
6496 " Pointer: Pointer,\n"6495 " Pointer: Pointer,\n"
6497 " Slice: Slice,\n"
6498 " Array: Array,\n"6496 " Array: Array,\n"
6499 " Struct: Struct,\n"6497 " Struct: Struct,\n"
6500 " ComptimeFloat: void,\n"6498 " ComptimeFloat: void,\n"
...@@ -6524,13 +6522,18 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6524,13 +6522,18 @@ static void define_builtin_compile_vars(CodeGen *g) {
6524 " };\n"6522 " };\n"
6525 "\n"6523 "\n"
6526 " pub const Pointer = struct {\n"6524 " pub const Pointer = struct {\n"
6525 " size: Size,\n"
6527 " is_const: bool,\n"6526 " is_const: bool,\n"
6528 " is_volatile: bool,\n"6527 " is_volatile: bool,\n"
6529 " alignment: u32,\n"6528 " alignment: u32,\n"
6530 " child: type,\n"6529 " child: type,\n"
6531 " };\n"
6532 "\n"6530 "\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"
6534 "\n"6537 "\n"
6535 " pub const Array = struct {\n"6538 " pub const Array = struct {\n"
6536 " len: usize,\n"6539 " len: usize,\n"
src/ir.cpp+50-30
...@@ -16222,8 +16222,7 @@ static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop...@@ -16222,8 +16222,7 @@ static bool ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop
16222 return true;16222 return true;
16223}16223}
1622416224
16225static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry)16225static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) {
16226{
16227 assert(type_entry != nullptr);16226 assert(type_entry != nullptr);
16228 assert(!type_is_invalid(type_entry));16227 assert(!type_is_invalid(type_entry));
1622916228
...@@ -16248,38 +16247,67 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16248,38 +16247,67 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16248 enum_field_val->data.x_struct.fields = inner_fields;16247 enum_field_val->data.x_struct.fields = inner_fields;
16249 };16248 };
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
16252 ConstExprValue *result = create_const_vals(1);16267 ConstExprValue *result = create_const_vals(1);
16253 result->special = ConstValSpecialStatic;16268 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);
16257 result->data.x_struct.fields = fields;16272 result->data.x_struct.fields = fields;
1625816273
16259 // is_const: bool16274 // size: Size
16260 ensure_field_index(result->type, "is_const", 0);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));
16261 fields[0].special = ConstValSpecialStatic;16279 fields[0].special = ConstValSpecialStatic;
16262 fields[0].type = ira->codegen->builtin_types.entry_bool;16280 fields[0].type = type_info_pointer_size_type;
16263 fields[0].data.x_bool = ptr_type_entry->data.pointer.is_const;16281 bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index);
16264 // is_volatile: bool16282
16265 ensure_field_index(result->type, "is_volatile", 1);16283 // is_const: bool
16284 ensure_field_index(result->type, "is_const", 1);
16266 fields[1].special = ConstValSpecialStatic;16285 fields[1].special = ConstValSpecialStatic;
16267 fields[1].type = ira->codegen->builtin_types.entry_bool;16286 fields[1].type = ira->codegen->builtin_types.entry_bool;
16268 fields[1].data.x_bool = ptr_type_entry->data.pointer.is_volatile;16287 fields[1].data.x_bool = attrs_type->data.pointer.is_const;
16269 // alignment: u3216288 // is_volatile: bool
16270 ensure_field_index(result->type, "alignment", 2);16289 ensure_field_index(result->type, "is_volatile", 2);
16271 fields[2].special = ConstValSpecialStatic;16290 fields[2].special = ConstValSpecialStatic;
16272 fields[2].type = ira->codegen->builtin_types.entry_u32;16291 fields[2].type = ira->codegen->builtin_types.entry_bool;
16273 bigint_init_unsigned(&fields[2].data.x_bigint, ptr_type_entry->data.pointer.alignment);16292 fields[2].data.x_bool = attrs_type->data.pointer.is_volatile;
16274 // child: type16293 // alignment: u32
16275 ensure_field_index(result->type, "child", 3);16294 ensure_field_index(result->type, "alignment", 3);
16276 fields[3].special = ConstValSpecialStatic;16295 fields[3].special = ConstValSpecialStatic;
16277 fields[3].type = ira->codegen->builtin_types.entry_type;16296 fields[3].type = ira->codegen->builtin_types.entry_u32;
16278 fields[3].data.x_type = ptr_type_entry->data.pointer.child_type;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
16280 return result;16304 return result;
16281 };16305 };
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
16283 ConstExprValue *result = nullptr;16311 ConstExprValue *result = nullptr;
16284 switch (type_entry->id)16312 switch (type_entry->id)
16285 {16313 {
...@@ -16348,7 +16376,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16348,7 +16376,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16348 }16376 }
16349 case TypeTableEntryIdPointer:16377 case TypeTableEntryIdPointer:
16350 {16378 {
16351 result = create_ptr_like_type_info("Pointer", type_entry);16379 result = create_ptr_like_type_info(type_entry);
16352 break;16380 break;
16353 }16381 }
16354 case TypeTableEntryIdArray:16382 case TypeTableEntryIdArray:
...@@ -16621,15 +16649,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16621,15 +16649,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16621 case TypeTableEntryIdStruct:16649 case TypeTableEntryIdStruct:
16622 {16650 {
16623 if (type_entry->data.structure.is_slice) {16651 if (type_entry->data.structure.is_slice) {
16624 Buf ptr_field_name = BUF_INIT;16652 result = create_ptr_like_type_info(type_entry);
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);
16633 break;16653 break;
16634 }16654 }
1663516655
std/fmt/index.zig+19-12
...@@ -97,7 +97,11 @@ pub fn formatType(...@@ -97,7 +97,11 @@ pub fn formatType(
97 output: fn (@typeOf(context), []const u8) Errors!void,97 output: fn (@typeOf(context), []const u8) Errors!void,
98) Errors!void {98) Errors!void {
99 const T = @typeOf(value);99 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)) {
101 builtin.TypeId.Int, builtin.TypeId.Float => {105 builtin.TypeId.Int, builtin.TypeId.Float => {
102 return formatValue(value, fmt, context, Errors, output);106 return formatValue(value, fmt, context, Errors, output);
103 },107 },
...@@ -125,12 +129,13 @@ pub fn formatType(...@@ -125,12 +129,13 @@ pub fn formatType(
125 try output(context, "error.");129 try output(context, "error.");
126 return output(context, @errorName(value));130 return output(context, @errorName(value));
127 },131 },
128 builtin.TypeId.Pointer => {132 builtin.TypeId.Pointer => |ptr_info| switch (ptr_info.size) {
129 switch (@typeId(T.Child)) {133 builtin.TypeInfo.Pointer.Size.One => switch (@typeInfo(ptr_info.child)) {
130 builtin.TypeId.Array => {134 builtin.TypeId.Array => |info| {
131 if (T.Child.Child == u8) {135 if (info.child == u8) {
132 return formatText(value, fmt, context, Errors, output);136 return formatText(value, fmt, context, Errors, output);
133 }137 }
138 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
134 },139 },
135 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {140 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
136 const has_cust_fmt = comptime cf: {141 const has_cust_fmt = comptime cf: {
...@@ -154,14 +159,16 @@ pub fn formatType(...@@ -154,14 +159,16 @@ pub fn formatType(
154 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));159 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
155 },160 },
156 else => return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)),161 else => return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)),
157 }162 },
158 },163 builtin.TypeInfo.Pointer.Size.Many => {
159 else => if (@canImplicitCast([]const u8, value)) {164 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
160 const casted_value = ([]const u8)(value);165 },
161 return output(context, casted_value);166 builtin.TypeInfo.Pointer.Size.Slice => {
162 } else {167 const casted_value = ([]const u8)(value);
163 @compileError("Unable to format type '" ++ @typeName(T) ++ "'");168 return output(context, casted_value);
169 },
164 },170 },
171 else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
165 }172 }
166}173}
167174
test/cases/type_info.zig+25-8
...@@ -39,12 +39,28 @@ test "type info: pointer type info" {...@@ -39,12 +39,28 @@ test "type info: pointer type info" {
39fn testPointer() void {39fn testPointer() void {
40 const u32_ptr_info = @typeInfo(*u32);40 const u32_ptr_info = @typeInfo(*u32);
41 assert(TypeId(u32_ptr_info) == TypeId.Pointer);41 assert(TypeId(u32_ptr_info) == TypeId.Pointer);
42 assert(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);
42 assert(u32_ptr_info.Pointer.is_const == false);43 assert(u32_ptr_info.Pointer.is_const == false);
43 assert(u32_ptr_info.Pointer.is_volatile == false);44 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));
45 assert(u32_ptr_info.Pointer.child == u32);46 assert(u32_ptr_info.Pointer.child == u32);
46}47}
4748
49test "type info: unknown length pointer type info" {
50 testUnknownLenPtr();
51 comptime testUnknownLenPtr();
52}
53
54fn 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
48test "type info: slice type info" {64test "type info: slice type info" {
49 testSlice();65 testSlice();
50 comptime testSlice();66 comptime testSlice();
...@@ -52,11 +68,12 @@ test "type info: slice type info" {...@@ -52,11 +68,12 @@ test "type info: slice type info" {
5268
53fn testSlice() void {69fn testSlice() void {
54 const u32_slice_info = @typeInfo([]u32);70 const u32_slice_info = @typeInfo([]u32);
55 assert(TypeId(u32_slice_info) == TypeId.Slice);71 assert(TypeId(u32_slice_info) == TypeId.Pointer);
56 assert(u32_slice_info.Slice.is_const == false);72 assert(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);
57 assert(u32_slice_info.Slice.is_volatile == false);73 assert(u32_slice_info.Pointer.is_const == false);
58 assert(u32_slice_info.Slice.alignment == 4);74 assert(u32_slice_info.Pointer.is_volatile == false);
59 assert(u32_slice_info.Slice.child == u32);75 assert(u32_slice_info.Pointer.alignment == 4);
76 assert(u32_slice_info.Pointer.child == u32);
60}77}
6178
62test "type info: array type info" {79test "type info: array type info" {
...@@ -149,11 +166,11 @@ fn testUnion() void {...@@ -149,11 +166,11 @@ fn testUnion() void {
149 assert(TypeId(typeinfo_info) == TypeId.Union);166 assert(TypeId(typeinfo_info) == TypeId.Union);
150 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);167 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
151 assert(typeinfo_info.Union.tag_type == TypeId);168 assert(typeinfo_info.Union.tag_type == TypeId);
152 assert(typeinfo_info.Union.fields.len == 26);169 assert(typeinfo_info.Union.fields.len == 25);
153 assert(typeinfo_info.Union.fields[4].enum_field != null);170 assert(typeinfo_info.Union.fields[4].enum_field != null);
154 assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);171 assert((??typeinfo_info.Union.fields[4].enum_field).value == 4);
155 assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));172 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
158 const TestNoTagUnion = union {175 const TestNoTagUnion = union {
159 Foo: void,176 Foo: void,