authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-19 11:46:32-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-06-19 11:46:32-04:00
log85422d7aeadc453ec621d0624f394c3f4e3f619f
treea079e4ca9620ca618b7c0e09aa8e99df1e2a4ae5
parent9f2324389d4aec5d38e840ab09fd9af558a77913
parent811539f8ee88366fea744ecfe251413b5dd774cc
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #1136 from alexnask/typeinfo_improvements

@typeInfo now uses optional types instead of @typeOf(undefined)

4 files changed, 66 insertions(+), 45 deletions(-)

doc/langref.html.in+5-5
...@@ -5755,7 +5755,7 @@ pub const TypeInfo = union(TypeId) {...@@ -5755,7 +5755,7 @@ pub const TypeInfo = union(TypeId) {
57555755
5756 pub const Union = struct {5756 pub const Union = struct {
5757 layout: ContainerLayout,5757 layout: ContainerLayout,
5758 tag_type: type,5758 tag_type: ?type,
5759 fields: []UnionField,5759 fields: []UnionField,
5760 defs: []Definition,5760 defs: []Definition,
5761 };5761 };
...@@ -5772,20 +5772,20 @@ pub const TypeInfo = union(TypeId) {...@@ -5772,20 +5772,20 @@ pub const TypeInfo = union(TypeId) {
5772 pub const FnArg = struct {5772 pub const FnArg = struct {
5773 is_generic: bool,5773 is_generic: bool,
5774 is_noalias: bool,5774 is_noalias: bool,
5775 arg_type: type,5775 arg_type: ?type,
5776 };5776 };
57775777
5778 pub const Fn = struct {5778 pub const Fn = struct {
5779 calling_convention: CallingConvention,5779 calling_convention: CallingConvention,
5780 is_generic: bool,5780 is_generic: bool,
5781 is_var_args: bool,5781 is_var_args: bool,
5782 return_type: type,5782 return_type: ?type,
5783 async_allocator_type: type,5783 async_allocator_type: ?type,
5784 args: []FnArg,5784 args: []FnArg,
5785 };5785 };
57865786
5787 pub const Promise = struct {5787 pub const Promise = struct {
5788 child: type,5788 child: ?type,
5789 };5789 };
57905790
5791 pub const Definition = struct {5791 pub const Definition = struct {
src/codegen.cpp+5-5
...@@ -6638,7 +6638,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -6638,7 +6638,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
6638 "\n"6638 "\n"
6639 " pub const Union = struct {\n"6639 " pub const Union = struct {\n"
6640 " layout: ContainerLayout,\n"6640 " layout: ContainerLayout,\n"
6641 " tag_type: type,\n"6641 " tag_type: ?type,\n"
6642 " fields: []UnionField,\n"6642 " fields: []UnionField,\n"
6643 " defs: []Definition,\n"6643 " defs: []Definition,\n"
6644 " };\n"6644 " };\n"
...@@ -6655,20 +6655,20 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -6655,20 +6655,20 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
6655 " pub const FnArg = struct {\n"6655 " pub const FnArg = struct {\n"
6656 " is_generic: bool,\n"6656 " is_generic: bool,\n"
6657 " is_noalias: bool,\n"6657 " is_noalias: bool,\n"
6658 " arg_type: type,\n"6658 " arg_type: ?type,\n"
6659 " };\n"6659 " };\n"
6660 "\n"6660 "\n"
6661 " pub const Fn = struct {\n"6661 " pub const Fn = struct {\n"
6662 " calling_convention: CallingConvention,\n"6662 " calling_convention: CallingConvention,\n"
6663 " is_generic: bool,\n"6663 " is_generic: bool,\n"
6664 " is_var_args: bool,\n"6664 " is_var_args: bool,\n"
6665 " return_type: type,\n"6665 " return_type: ?type,\n"
6666 " async_allocator_type: type,\n"6666 " async_allocator_type: ?type,\n"
6667 " args: []FnArg,\n"6667 " args: []FnArg,\n"
6668 " };\n"6668 " };\n"
6669 "\n"6669 "\n"
6670 " pub const Promise = struct {\n"6670 " pub const Promise = struct {\n"
6671 " child: type,\n"6671 " child: ?type,\n"
6672 " };\n"6672 " };\n"
6673 "\n"6673 "\n"
6674 " pub const Definition = struct {\n"6674 " pub const Definition = struct {\n"
src/ir.cpp+48-27
...@@ -16789,16 +16789,20 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16789,16 +16789,20 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16789 ConstExprValue *fields = create_const_vals(1);16789 ConstExprValue *fields = create_const_vals(1);
16790 result->data.x_struct.fields = fields;16790 result->data.x_struct.fields = fields;
1679116791
16792 // @TODO ?type instead of using @typeOf(undefined) when we have no type.16792 // child: ?type
16793 // child: type
16794 ensure_field_index(result->type, "child", 0);16793 ensure_field_index(result->type, "child", 0);
16795 fields[0].special = ConstValSpecialStatic;16794 fields[0].special = ConstValSpecialStatic;
16796 fields[0].type = ira->codegen->builtin_types.entry_type;16795 fields[0].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
1679716796
16798 if (type_entry->data.promise.result_type == nullptr)16797 if (type_entry->data.promise.result_type == nullptr)
16799 fields[0].data.x_type = ira->codegen->builtin_types.entry_undef;16798 fields[0].data.x_optional = nullptr;
16800 else16799 else {
16801 fields[0].data.x_type = type_entry->data.promise.result_type;16800 ConstExprValue *child_type = create_const_vals(1);
16801 child_type->special = ConstValSpecialStatic;
16802 child_type->type = ira->codegen->builtin_types.entry_type;
16803 child_type->data.x_type = type_entry->data.promise.result_type;
16804 fields[0].data.x_optional = child_type;
16805 }
1680216806
16803 break;16807 break;
16804 }16808 }
...@@ -16939,19 +16943,23 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16939,19 +16943,23 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16939 fields[0].special = ConstValSpecialStatic;16943 fields[0].special = ConstValSpecialStatic;
16940 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout");16944 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout");
16941 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout);16945 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout);
16942 // tag_type: type16946 // tag_type: ?type
16943 ensure_field_index(result->type, "tag_type", 1);16947 ensure_field_index(result->type, "tag_type", 1);
16944 fields[1].special = ConstValSpecialStatic;16948 fields[1].special = ConstValSpecialStatic;
16945 fields[1].type = ira->codegen->builtin_types.entry_type;16949 fields[1].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
16946 // @TODO ?type instead of using @typeOf(undefined) when we have no type.16950
16947 AstNode *union_decl_node = type_entry->data.unionation.decl_node;16951 AstNode *union_decl_node = type_entry->data.unionation.decl_node;
16948 if (union_decl_node->data.container_decl.auto_enum ||16952 if (union_decl_node->data.container_decl.auto_enum ||
16949 union_decl_node->data.container_decl.init_arg_expr != nullptr)16953 union_decl_node->data.container_decl.init_arg_expr != nullptr)
16950 {16954 {
16951 fields[1].data.x_type = type_entry->data.unionation.tag_type;16955 ConstExprValue *tag_type = create_const_vals(1);
16956 tag_type->special = ConstValSpecialStatic;
16957 tag_type->type = ira->codegen->builtin_types.entry_type;
16958 tag_type->data.x_type = type_entry->data.unionation.tag_type;
16959 fields[1].data.x_optional = tag_type;
16952 }16960 }
16953 else16961 else
16954 fields[1].data.x_type = ira->codegen->builtin_types.entry_undef;16962 fields[1].data.x_optional = nullptr;
16955 // fields: []TypeInfo.UnionField16963 // fields: []TypeInfo.UnionField
16956 ensure_field_index(result->type, "fields", 2);16964 ensure_field_index(result->type, "fields", 2);
1695716965
...@@ -16980,7 +16988,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16980,7 +16988,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16980 inner_fields[1].special = ConstValSpecialStatic;16988 inner_fields[1].special = ConstValSpecialStatic;
16981 inner_fields[1].type = get_maybe_type(ira->codegen, type_info_enum_field_type);16989 inner_fields[1].type = get_maybe_type(ira->codegen, type_info_enum_field_type);
1698216990
16983 if (fields[1].data.x_type == ira->codegen->builtin_types.entry_undef) {16991 if (fields[1].data.x_optional == nullptr) {
16984 inner_fields[1].data.x_optional = nullptr;16992 inner_fields[1].data.x_optional = nullptr;
16985 } else {16993 } else {
16986 inner_fields[1].data.x_optional = create_const_vals(1);16994 inner_fields[1].data.x_optional = create_const_vals(1);
...@@ -17089,8 +17097,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -17089,8 +17097,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
17089 ConstExprValue *fields = create_const_vals(6);17097 ConstExprValue *fields = create_const_vals(6);
17090 result->data.x_struct.fields = fields;17098 result->data.x_struct.fields = fields;
1709117099
17092 // @TODO Fix type = undefined with ?type
17093
17094 // calling_convention: TypeInfo.CallingConvention17100 // calling_convention: TypeInfo.CallingConvention
17095 ensure_field_index(result->type, "calling_convention", 0);17101 ensure_field_index(result->type, "calling_convention", 0);
17096 fields[0].special = ConstValSpecialStatic;17102 fields[0].special = ConstValSpecialStatic;
...@@ -17108,22 +17114,32 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -17108,22 +17114,32 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
17108 fields[2].special = ConstValSpecialStatic;17114 fields[2].special = ConstValSpecialStatic;
17109 fields[2].type = ira->codegen->builtin_types.entry_bool;17115 fields[2].type = ira->codegen->builtin_types.entry_bool;
17110 fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;17116 fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;
17111 // return_type: type17117 // return_type: ?type
17112 ensure_field_index(result->type, "return_type", 3);17118 ensure_field_index(result->type, "return_type", 3);
17113 fields[3].special = ConstValSpecialStatic;17119 fields[3].special = ConstValSpecialStatic;
17114 fields[3].type = ira->codegen->builtin_types.entry_type;17120 fields[3].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
17115 if (type_entry->data.fn.fn_type_id.return_type == nullptr)17121 if (type_entry->data.fn.fn_type_id.return_type == nullptr)
17116 fields[3].data.x_type = ira->codegen->builtin_types.entry_undef;17122 fields[3].data.x_optional = nullptr;
17117 else17123 else {
17118 fields[3].data.x_type = type_entry->data.fn.fn_type_id.return_type;17124 ConstExprValue *return_type = create_const_vals(1);
17125 return_type->special = ConstValSpecialStatic;
17126 return_type->type = ira->codegen->builtin_types.entry_type;
17127 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
17128 fields[3].data.x_optional = return_type;
17129 }
17119 // async_allocator_type: type17130 // async_allocator_type: type
17120 ensure_field_index(result->type, "async_allocator_type", 4);17131 ensure_field_index(result->type, "async_allocator_type", 4);
17121 fields[4].special = ConstValSpecialStatic;17132 fields[4].special = ConstValSpecialStatic;
17122 fields[4].type = ira->codegen->builtin_types.entry_type;17133 fields[4].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
17123 if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr)17134 if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr)
17124 fields[4].data.x_type = ira->codegen->builtin_types.entry_undef;17135 fields[4].data.x_optional = nullptr;
17125 else17136 else {
17126 fields[4].data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type;17137 ConstExprValue *async_alloc_type = create_const_vals(1);
17138 async_alloc_type->special = ConstValSpecialStatic;
17139 async_alloc_type->type = ira->codegen->builtin_types.entry_type;
17140 async_alloc_type->data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type;
17141 fields[4].data.x_optional = async_alloc_type;
17142 }
17127 // args: []TypeInfo.FnArg17143 // args: []TypeInfo.FnArg
17128 TypeTableEntry *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg");17144 TypeTableEntry *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg");
17129 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count -17145 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count -
...@@ -17157,12 +17173,17 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -17157,12 +17173,17 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
17157 inner_fields[1].type = ira->codegen->builtin_types.entry_bool;17173 inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
17158 inner_fields[1].data.x_bool = fn_param_info->is_noalias;17174 inner_fields[1].data.x_bool = fn_param_info->is_noalias;
17159 inner_fields[2].special = ConstValSpecialStatic;17175 inner_fields[2].special = ConstValSpecialStatic;
17160 inner_fields[2].type = ira->codegen->builtin_types.entry_type;17176 inner_fields[2].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
1716117177
17162 if (arg_is_generic)17178 if (arg_is_generic)
17163 inner_fields[2].data.x_type = ira->codegen->builtin_types.entry_undef;17179 inner_fields[2].data.x_optional = nullptr;
17164 else17180 else {
17165 inner_fields[2].data.x_type = fn_param_info->type;17181 ConstExprValue *arg_type = create_const_vals(1);
17182 arg_type->special = ConstValSpecialStatic;
17183 arg_type->type = ira->codegen->builtin_types.entry_type;
17184 arg_type->data.x_type = fn_param_info->type;
17185 inner_fields[2].data.x_optional = arg_type;
17186 }
1716617187
17167 fn_arg_val->data.x_struct.fields = inner_fields;17188 fn_arg_val->data.x_struct.fields = inner_fields;
17168 fn_arg_val->data.x_struct.parent.id = ConstParentIdArray;17189 fn_arg_val->data.x_struct.parent.id = ConstParentIdArray;
test/cases/type_info.zig+8-8
...@@ -107,11 +107,11 @@ test "type info: promise info" {...@@ -107,11 +107,11 @@ test "type info: promise info" {
107fn testPromise() void {107fn testPromise() void {
108 const null_promise_info = @typeInfo(promise);108 const null_promise_info = @typeInfo(promise);
109 assert(TypeId(null_promise_info) == TypeId.Promise);109 assert(TypeId(null_promise_info) == TypeId.Promise);
110 assert(null_promise_info.Promise.child == @typeOf(undefined));110 assert(null_promise_info.Promise.child == null);
111111
112 const promise_info = @typeInfo(promise->usize);112 const promise_info = @typeInfo(promise->usize);
113 assert(TypeId(promise_info) == TypeId.Promise);113 assert(TypeId(promise_info) == TypeId.Promise);
114 assert(promise_info.Promise.child == usize);114 assert(promise_info.Promise.child.? == usize);
115}115}
116116
117test "type info: error set, error union info" {117test "type info: error set, error union info" {
...@@ -165,7 +165,7 @@ fn testUnion() void {...@@ -165,7 +165,7 @@ fn testUnion() void {
165 const typeinfo_info = @typeInfo(TypeInfo);165 const typeinfo_info = @typeInfo(TypeInfo);
166 assert(TypeId(typeinfo_info) == TypeId.Union);166 assert(TypeId(typeinfo_info) == TypeId.Union);
167 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);167 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
168 assert(typeinfo_info.Union.tag_type == TypeId);168 assert(typeinfo_info.Union.tag_type.? == TypeId);
169 assert(typeinfo_info.Union.fields.len == 25);169 assert(typeinfo_info.Union.fields.len == 25);
170 assert(typeinfo_info.Union.fields[4].enum_field != null);170 assert(typeinfo_info.Union.fields[4].enum_field != null);
171 assert(typeinfo_info.Union.fields[4].enum_field.?.value == 4);171 assert(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
...@@ -179,7 +179,7 @@ fn testUnion() void {...@@ -179,7 +179,7 @@ fn testUnion() void {
179179
180 const notag_union_info = @typeInfo(TestNoTagUnion);180 const notag_union_info = @typeInfo(TestNoTagUnion);
181 assert(TypeId(notag_union_info) == TypeId.Union);181 assert(TypeId(notag_union_info) == TypeId.Union);
182 assert(notag_union_info.Union.tag_type == @typeOf(undefined));182 assert(notag_union_info.Union.tag_type == null);
183 assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);183 assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
184 assert(notag_union_info.Union.fields.len == 2);184 assert(notag_union_info.Union.fields.len == 2);
185 assert(notag_union_info.Union.fields[0].enum_field == null);185 assert(notag_union_info.Union.fields[0].enum_field == null);
...@@ -191,7 +191,7 @@ fn testUnion() void {...@@ -191,7 +191,7 @@ fn testUnion() void {
191191
192 const extern_union_info = @typeInfo(TestExternUnion);192 const extern_union_info = @typeInfo(TestExternUnion);
193 assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);193 assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);
194 assert(extern_union_info.Union.tag_type == @typeOf(undefined));194 assert(extern_union_info.Union.tag_type == null);
195 assert(extern_union_info.Union.fields[0].enum_field == null);195 assert(extern_union_info.Union.fields[0].enum_field == null);
196 assert(extern_union_info.Union.fields[0].field_type == *c_void);196 assert(extern_union_info.Union.fields[0].field_type == *c_void);
197}197}
...@@ -238,13 +238,13 @@ fn testFunction() void {...@@ -238,13 +238,13 @@ fn testFunction() void {
238 assert(fn_info.Fn.is_generic);238 assert(fn_info.Fn.is_generic);
239 assert(fn_info.Fn.args.len == 2);239 assert(fn_info.Fn.args.len == 2);
240 assert(fn_info.Fn.is_var_args);240 assert(fn_info.Fn.is_var_args);
241 assert(fn_info.Fn.return_type == @typeOf(undefined));241 assert(fn_info.Fn.return_type == null);
242 assert(fn_info.Fn.async_allocator_type == @typeOf(undefined));242 assert(fn_info.Fn.async_allocator_type == null);
243243
244 const test_instance: TestStruct = undefined;244 const test_instance: TestStruct = undefined;
245 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));245 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
246 assert(TypeId(bound_fn_info) == TypeId.BoundFn);246 assert(TypeId(bound_fn_info) == TypeId.BoundFn);
247 assert(bound_fn_info.BoundFn.args[0].arg_type == *const TestStruct);247 assert(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);
248}248}
249249
250fn foo(comptime a: usize, b: bool, args: ...) usize {250fn foo(comptime a: usize, b: bool, args: ...) usize {