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) {
57555755
57565756 pub const Union = struct {
57575757 layout: ContainerLayout,
5758 tag_type: type,
5758 tag_type: ?type,
57595759 fields: []UnionField,
57605760 defs: []Definition,
57615761 };
......@@ -5772,20 +5772,20 @@ pub const TypeInfo = union(TypeId) {
57725772 pub const FnArg = struct {
57735773 is_generic: bool,
57745774 is_noalias: bool,
5775 arg_type: type,
5775 arg_type: ?type,
57765776 };
57775777
57785778 pub const Fn = struct {
57795779 calling_convention: CallingConvention,
57805780 is_generic: bool,
57815781 is_var_args: bool,
5782 return_type: type,
5783 async_allocator_type: type,
5782 return_type: ?type,
5783 async_allocator_type: ?type,
57845784 args: []FnArg,
57855785 };
57865786
57875787 pub const Promise = struct {
5788 child: type,
5788 child: ?type,
57895789 };
57905790
57915791 pub const Definition = struct {
src/codegen.cpp+5-5
......@@ -6638,7 +6638,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
66386638 "\n"
66396639 " pub const Union = struct {\n"
66406640 " layout: ContainerLayout,\n"
6641 " tag_type: type,\n"
6641 " tag_type: ?type,\n"
66426642 " fields: []UnionField,\n"
66436643 " defs: []Definition,\n"
66446644 " };\n"
......@@ -6655,20 +6655,20 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
66556655 " pub const FnArg = struct {\n"
66566656 " is_generic: bool,\n"
66576657 " is_noalias: bool,\n"
6658 " arg_type: type,\n"
6658 " arg_type: ?type,\n"
66596659 " };\n"
66606660 "\n"
66616661 " pub const Fn = struct {\n"
66626662 " calling_convention: CallingConvention,\n"
66636663 " is_generic: bool,\n"
66646664 " is_var_args: bool,\n"
6665 " return_type: type,\n"
6666 " async_allocator_type: type,\n"
6665 " return_type: ?type,\n"
6666 " async_allocator_type: ?type,\n"
66676667 " args: []FnArg,\n"
66686668 " };\n"
66696669 "\n"
66706670 " pub const Promise = struct {\n"
6671 " child: type,\n"
6671 " child: ?type,\n"
66726672 " };\n"
66736673 "\n"
66746674 " 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
1678916789 ConstExprValue *fields = create_const_vals(1);
1679016790 result->data.x_struct.fields = fields;
1679116791
16792 // @TODO ?type instead of using @typeOf(undefined) when we have no type.
16793 // child: type
16792 // child: ?type
1679416793 ensure_field_index(result->type, "child", 0);
1679516794 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
1679816797 if (type_entry->data.promise.result_type == nullptr)
16799 fields[0].data.x_type = ira->codegen->builtin_types.entry_undef;
16800 else
16801 fields[0].data.x_type = type_entry->data.promise.result_type;
16798 fields[0].data.x_optional = nullptr;
16799 else {
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
1680316807 break;
1680416808 }
......@@ -16939,19 +16943,23 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
1693916943 fields[0].special = ConstValSpecialStatic;
1694016944 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout");
1694116945 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout);
16942 // tag_type: type
16946 // tag_type: ?type
1694316947 ensure_field_index(result->type, "tag_type", 1);
1694416948 fields[1].special = ConstValSpecialStatic;
16945 fields[1].type = ira->codegen->builtin_types.entry_type;
16946 // @TODO ?type instead of using @typeOf(undefined) when we have no type.
16949 fields[1].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_type);
16950
1694716951 AstNode *union_decl_node = type_entry->data.unionation.decl_node;
1694816952 if (union_decl_node->data.container_decl.auto_enum ||
1694916953 union_decl_node->data.container_decl.init_arg_expr != nullptr)
1695016954 {
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;
1695216960 }
1695316961 else
16954 fields[1].data.x_type = ira->codegen->builtin_types.entry_undef;
16962 fields[1].data.x_optional = nullptr;
1695516963 // fields: []TypeInfo.UnionField
1695616964 ensure_field_index(result->type, "fields", 2);
1695716965
......@@ -16980,7 +16988,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
1698016988 inner_fields[1].special = ConstValSpecialStatic;
1698116989 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) {
1698416992 inner_fields[1].data.x_optional = nullptr;
1698516993 } else {
1698616994 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
1708917097 ConstExprValue *fields = create_const_vals(6);
1709017098 result->data.x_struct.fields = fields;
1709117099
17092 // @TODO Fix type = undefined with ?type
17093
1709417100 // calling_convention: TypeInfo.CallingConvention
1709517101 ensure_field_index(result->type, "calling_convention", 0);
1709617102 fields[0].special = ConstValSpecialStatic;
......@@ -17108,22 +17114,32 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
1710817114 fields[2].special = ConstValSpecialStatic;
1710917115 fields[2].type = ira->codegen->builtin_types.entry_bool;
1711017116 fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;
17111 // return_type: type
17117 // return_type: ?type
1711217118 ensure_field_index(result->type, "return_type", 3);
1711317119 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);
1711517121 if (type_entry->data.fn.fn_type_id.return_type == nullptr)
17116 fields[3].data.x_type = ira->codegen->builtin_types.entry_undef;
17117 else
17118 fields[3].data.x_type = type_entry->data.fn.fn_type_id.return_type;
17122 fields[3].data.x_optional = nullptr;
17123 else {
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 }
1711917130 // async_allocator_type: type
1712017131 ensure_field_index(result->type, "async_allocator_type", 4);
1712117132 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);
1712317134 if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr)
17124 fields[4].data.x_type = ira->codegen->builtin_types.entry_undef;
17125 else
17126 fields[4].data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type;
17135 fields[4].data.x_optional = nullptr;
17136 else {
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 }
1712717143 // args: []TypeInfo.FnArg
1712817144 TypeTableEntry *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg");
1712917145 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
1715717173 inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
1715817174 inner_fields[1].data.x_bool = fn_param_info->is_noalias;
1715917175 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
1716217178 if (arg_is_generic)
17163 inner_fields[2].data.x_type = ira->codegen->builtin_types.entry_undef;
17164 else
17165 inner_fields[2].data.x_type = fn_param_info->type;
17179 inner_fields[2].data.x_optional = nullptr;
17180 else {
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
1716717188 fn_arg_val->data.x_struct.fields = inner_fields;
1716817189 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" {
107107fn testPromise() void {
108108 const null_promise_info = @typeInfo(promise);
109109 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
112112 const promise_info = @typeInfo(promise->usize);
113113 assert(TypeId(promise_info) == TypeId.Promise);
114 assert(promise_info.Promise.child == usize);
114 assert(promise_info.Promise.child.? == usize);
115115}
116116
117117test "type info: error set, error union info" {
......@@ -165,7 +165,7 @@ fn testUnion() void {
165165 const typeinfo_info = @typeInfo(TypeInfo);
166166 assert(TypeId(typeinfo_info) == TypeId.Union);
167167 assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
168 assert(typeinfo_info.Union.tag_type == TypeId);
168 assert(typeinfo_info.Union.tag_type.? == TypeId);
169169 assert(typeinfo_info.Union.fields.len == 25);
170170 assert(typeinfo_info.Union.fields[4].enum_field != null);
171171 assert(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
......@@ -179,7 +179,7 @@ fn testUnion() void {
179179
180180 const notag_union_info = @typeInfo(TestNoTagUnion);
181181 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);
183183 assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
184184 assert(notag_union_info.Union.fields.len == 2);
185185 assert(notag_union_info.Union.fields[0].enum_field == null);
......@@ -191,7 +191,7 @@ fn testUnion() void {
191191
192192 const extern_union_info = @typeInfo(TestExternUnion);
193193 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);
195195 assert(extern_union_info.Union.fields[0].enum_field == null);
196196 assert(extern_union_info.Union.fields[0].field_type == *c_void);
197197}
......@@ -238,13 +238,13 @@ fn testFunction() void {
238238 assert(fn_info.Fn.is_generic);
239239 assert(fn_info.Fn.args.len == 2);
240240 assert(fn_info.Fn.is_var_args);
241 assert(fn_info.Fn.return_type == @typeOf(undefined));
242 assert(fn_info.Fn.async_allocator_type == @typeOf(undefined));
241 assert(fn_info.Fn.return_type == null);
242 assert(fn_info.Fn.async_allocator_type == null);
243243
244244 const test_instance: TestStruct = undefined;
245245 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
246246 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);
248248}
249249
250250fn foo(comptime a: usize, b: bool, args: ...) usize {