From 74b10c08d1bd0b64aa8175dff6dec178c7c3bbee Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 15 May 2018 14:11:41 -0400 Subject: [PATCH] fix @typeInfo not setting a field to comptime --- src/ir.cpp | 1 + test/cases/type_info.zig | 305 ++++++++++++++++++++++----------------- 2 files changed, 171 insertions(+), 135 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 31d22ca82..cade66065 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16549,6 +16549,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t { size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index); inner_fields[1].data.x_maybe = create_const_vals(1); + inner_fields[1].data.x_maybe->special = ConstValSpecialStatic; inner_fields[1].data.x_maybe->type = ira->codegen->builtin_types.entry_usize; bigint_init_unsigned(&inner_fields[1].data.x_maybe->data.x_bigint, byte_offset); } diff --git a/test/cases/type_info.zig b/test/cases/type_info.zig index f10703e3e..7bf1e6818 100644 --- a/test/cases/type_info.zig +++ b/test/cases/type_info.zig @@ -4,167 +4,199 @@ const TypeInfo = @import("builtin").TypeInfo; const TypeId = @import("builtin").TypeId; test "type info: tag type, void info" { - comptime { - assert(@TagType(TypeInfo) == TypeId); - const void_info = @typeInfo(void); - assert(TypeId(void_info) == TypeId.Void); - assert(void_info.Void == {}); - } + testBasic(); + comptime testBasic(); +} + +fn testBasic() void { + assert(@TagType(TypeInfo) == TypeId); + const void_info = @typeInfo(void); + assert(TypeId(void_info) == TypeId.Void); + assert(void_info.Void == {}); } test "type info: integer, floating point type info" { - comptime { - const u8_info = @typeInfo(u8); - assert(TypeId(u8_info) == TypeId.Int); - assert(!u8_info.Int.is_signed); - assert(u8_info.Int.bits == 8); + testIntFloat(); + comptime testIntFloat(); +} - const f64_info = @typeInfo(f64); - assert(TypeId(f64_info) == TypeId.Float); - assert(f64_info.Float.bits == 64); - } +fn testIntFloat() void { + const u8_info = @typeInfo(u8); + assert(TypeId(u8_info) == TypeId.Int); + assert(!u8_info.Int.is_signed); + assert(u8_info.Int.bits == 8); + + const f64_info = @typeInfo(f64); + assert(TypeId(f64_info) == TypeId.Float); + assert(f64_info.Float.bits == 64); } test "type info: pointer type info" { - comptime { - const u32_ptr_info = @typeInfo(&u32); - assert(TypeId(u32_ptr_info) == TypeId.Pointer); - assert(u32_ptr_info.Pointer.is_const == false); - assert(u32_ptr_info.Pointer.is_volatile == false); - assert(u32_ptr_info.Pointer.alignment == 4); - assert(u32_ptr_info.Pointer.child == u32); - } + testPointer(); + comptime testPointer(); +} + +fn testPointer() void { + const u32_ptr_info = @typeInfo(&u32); + assert(TypeId(u32_ptr_info) == TypeId.Pointer); + assert(u32_ptr_info.Pointer.is_const == false); + assert(u32_ptr_info.Pointer.is_volatile == false); + assert(u32_ptr_info.Pointer.alignment == 4); + assert(u32_ptr_info.Pointer.child == u32); } test "type info: slice type info" { - comptime { - const u32_slice_info = @typeInfo([]u32); - assert(TypeId(u32_slice_info) == TypeId.Slice); - assert(u32_slice_info.Slice.is_const == false); - assert(u32_slice_info.Slice.is_volatile == false); - assert(u32_slice_info.Slice.alignment == 4); - assert(u32_slice_info.Slice.child == u32); - } + testSlice(); + comptime testSlice(); +} + +fn testSlice() void { + const u32_slice_info = @typeInfo([]u32); + assert(TypeId(u32_slice_info) == TypeId.Slice); + assert(u32_slice_info.Slice.is_const == false); + assert(u32_slice_info.Slice.is_volatile == false); + assert(u32_slice_info.Slice.alignment == 4); + assert(u32_slice_info.Slice.child == u32); } test "type info: array type info" { - comptime { - const arr_info = @typeInfo([42]bool); - assert(TypeId(arr_info) == TypeId.Array); - assert(arr_info.Array.len == 42); - assert(arr_info.Array.child == bool); - } + testArray(); + comptime testArray(); +} + +fn testArray() void { + const arr_info = @typeInfo([42]bool); + assert(TypeId(arr_info) == TypeId.Array); + assert(arr_info.Array.len == 42); + assert(arr_info.Array.child == bool); } test "type info: nullable type info" { - comptime { - const null_info = @typeInfo(?void); - assert(TypeId(null_info) == TypeId.Nullable); - assert(null_info.Nullable.child == void); - } + testNullable(); + comptime testNullable(); +} + +fn testNullable() void { + const null_info = @typeInfo(?void); + assert(TypeId(null_info) == TypeId.Nullable); + assert(null_info.Nullable.child == void); } test "type info: promise info" { - comptime { - const null_promise_info = @typeInfo(promise); - assert(TypeId(null_promise_info) == TypeId.Promise); - assert(null_promise_info.Promise.child == @typeOf(undefined)); + testPromise(); + comptime testPromise(); +} - const promise_info = @typeInfo(promise->usize); - assert(TypeId(promise_info) == TypeId.Promise); - assert(promise_info.Promise.child == usize); - } +fn testPromise() void { + const null_promise_info = @typeInfo(promise); + assert(TypeId(null_promise_info) == TypeId.Promise); + assert(null_promise_info.Promise.child == @typeOf(undefined)); + const promise_info = @typeInfo(promise->usize); + assert(TypeId(promise_info) == TypeId.Promise); + assert(promise_info.Promise.child == usize); } test "type info: error set, error union info" { - comptime { - const TestErrorSet = error { - First, - Second, - Third, - }; + testErrorSet(); + comptime testErrorSet(); +} - const error_set_info = @typeInfo(TestErrorSet); - assert(TypeId(error_set_info) == TypeId.ErrorSet); - assert(error_set_info.ErrorSet.errors.len == 3); - assert(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First")); - assert(error_set_info.ErrorSet.errors[2].value == usize(TestErrorSet.Third)); +fn testErrorSet() void { + const TestErrorSet = error { + First, + Second, + Third, + }; - const error_union_info = @typeInfo(TestErrorSet!usize); - assert(TypeId(error_union_info) == TypeId.ErrorUnion); - assert(error_union_info.ErrorUnion.error_set == TestErrorSet); - assert(error_union_info.ErrorUnion.payload == usize); - } + const error_set_info = @typeInfo(TestErrorSet); + assert(TypeId(error_set_info) == TypeId.ErrorSet); + assert(error_set_info.ErrorSet.errors.len == 3); + assert(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First")); + assert(error_set_info.ErrorSet.errors[2].value == usize(TestErrorSet.Third)); + + const error_union_info = @typeInfo(TestErrorSet!usize); + assert(TypeId(error_union_info) == TypeId.ErrorUnion); + assert(error_union_info.ErrorUnion.error_set == TestErrorSet); + assert(error_union_info.ErrorUnion.payload == usize); } test "type info: enum info" { - comptime { - const Os = @import("builtin").Os; + testEnum(); + comptime testEnum(); +} - const os_info = @typeInfo(Os); - assert(TypeId(os_info) == TypeId.Enum); - assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto); - assert(os_info.Enum.fields.len == 32); - assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas")); - assert(os_info.Enum.fields[10].value == 10); - assert(os_info.Enum.tag_type == u5); - assert(os_info.Enum.defs.len == 0); - } +fn testEnum() void { + const Os = @import("builtin").Os; + + const os_info = @typeInfo(Os); + assert(TypeId(os_info) == TypeId.Enum); + assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto); + assert(os_info.Enum.fields.len == 32); + assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas")); + assert(os_info.Enum.fields[10].value == 10); + assert(os_info.Enum.tag_type == u5); + assert(os_info.Enum.defs.len == 0); } test "type info: union info" { - comptime { - const typeinfo_info = @typeInfo(TypeInfo); - assert(TypeId(typeinfo_info) == TypeId.Union); - assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto); - assert(typeinfo_info.Union.tag_type == TypeId); - assert(typeinfo_info.Union.fields.len == 26); - assert(typeinfo_info.Union.fields[4].enum_field != null); - assert((??typeinfo_info.Union.fields[4].enum_field).value == 4); - assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int)); - assert(typeinfo_info.Union.defs.len == 21); + testUnion(); + comptime testUnion(); +} - const TestNoTagUnion = union { - Foo: void, - Bar: u32, - }; +fn testUnion() void { + const typeinfo_info = @typeInfo(TypeInfo); + assert(TypeId(typeinfo_info) == TypeId.Union); + assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto); + assert(typeinfo_info.Union.tag_type == TypeId); + assert(typeinfo_info.Union.fields.len == 26); + assert(typeinfo_info.Union.fields[4].enum_field != null); + assert((??typeinfo_info.Union.fields[4].enum_field).value == 4); + assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int)); + assert(typeinfo_info.Union.defs.len == 21); - const notag_union_info = @typeInfo(TestNoTagUnion); - assert(TypeId(notag_union_info) == TypeId.Union); - assert(notag_union_info.Union.tag_type == @typeOf(undefined)); - assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto); - assert(notag_union_info.Union.fields.len == 2); - assert(notag_union_info.Union.fields[0].enum_field == null); - assert(notag_union_info.Union.fields[1].field_type == u32); + const TestNoTagUnion = union { + Foo: void, + Bar: u32, + }; - const TestExternUnion = extern union { - foo: &c_void, - }; + const notag_union_info = @typeInfo(TestNoTagUnion); + assert(TypeId(notag_union_info) == TypeId.Union); + assert(notag_union_info.Union.tag_type == @typeOf(undefined)); + assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto); + assert(notag_union_info.Union.fields.len == 2); + assert(notag_union_info.Union.fields[0].enum_field == null); + assert(notag_union_info.Union.fields[1].field_type == u32); - const extern_union_info = @typeInfo(TestExternUnion); - assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern); - assert(extern_union_info.Union.tag_type == @typeOf(undefined)); - assert(extern_union_info.Union.fields[0].enum_field == null); - assert(extern_union_info.Union.fields[0].field_type == &c_void); - } + const TestExternUnion = extern union { + foo: &c_void, + }; + + const extern_union_info = @typeInfo(TestExternUnion); + assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern); + assert(extern_union_info.Union.tag_type == @typeOf(undefined)); + assert(extern_union_info.Union.fields[0].enum_field == null); + assert(extern_union_info.Union.fields[0].field_type == &c_void); } test "type info: struct info" { - comptime { - const struct_info = @typeInfo(TestStruct); - assert(TypeId(struct_info) == TypeId.Struct); - assert(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed); - assert(struct_info.Struct.fields.len == 3); - assert(struct_info.Struct.fields[1].offset == null); - assert(struct_info.Struct.fields[2].field_type == &TestStruct); - assert(struct_info.Struct.defs.len == 2); - assert(struct_info.Struct.defs[0].is_pub); - assert(!struct_info.Struct.defs[0].data.Fn.is_extern); - assert(struct_info.Struct.defs[0].data.Fn.lib_name == null); - assert(struct_info.Struct.defs[0].data.Fn.return_type == void); - assert(struct_info.Struct.defs[0].data.Fn.fn_type == fn(&const TestStruct)void); - } + testStruct(); + comptime testStruct(); +} + +fn testStruct() void { + const struct_info = @typeInfo(TestStruct); + assert(TypeId(struct_info) == TypeId.Struct); + assert(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed); + assert(struct_info.Struct.fields.len == 3); + assert(struct_info.Struct.fields[1].offset == null); + assert(struct_info.Struct.fields[2].field_type == &TestStruct); + assert(struct_info.Struct.defs.len == 2); + assert(struct_info.Struct.defs[0].is_pub); + assert(!struct_info.Struct.defs[0].data.Fn.is_extern); + assert(struct_info.Struct.defs[0].data.Fn.lib_name == null); + assert(struct_info.Struct.defs[0].data.Fn.return_type == void); + assert(struct_info.Struct.defs[0].data.Fn.fn_type == fn(&const TestStruct)void); } const TestStruct = packed struct { @@ -178,21 +210,24 @@ const TestStruct = packed struct { }; test "type info: function type info" { - comptime { - const fn_info = @typeInfo(@typeOf(foo)); - assert(TypeId(fn_info) == TypeId.Fn); - assert(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified); - assert(fn_info.Fn.is_generic); - assert(fn_info.Fn.args.len == 2); - assert(fn_info.Fn.is_var_args); - assert(fn_info.Fn.return_type == @typeOf(undefined)); - assert(fn_info.Fn.async_allocator_type == @typeOf(undefined)); + testFunction(); + comptime testFunction(); +} - const test_instance: TestStruct = undefined; - const bound_fn_info = @typeInfo(@typeOf(test_instance.foo)); - assert(TypeId(bound_fn_info) == TypeId.BoundFn); - assert(bound_fn_info.BoundFn.args[0].arg_type == &const TestStruct); - } +fn testFunction() void { + const fn_info = @typeInfo(@typeOf(foo)); + assert(TypeId(fn_info) == TypeId.Fn); + assert(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified); + assert(fn_info.Fn.is_generic); + assert(fn_info.Fn.args.len == 2); + assert(fn_info.Fn.is_var_args); + assert(fn_info.Fn.return_type == @typeOf(undefined)); + assert(fn_info.Fn.async_allocator_type == @typeOf(undefined)); + + const test_instance: TestStruct = undefined; + const bound_fn_info = @typeInfo(@typeOf(test_instance.foo)); + assert(TypeId(bound_fn_info) == TypeId.BoundFn); + assert(bound_fn_info.BoundFn.args[0].arg_type == &const TestStruct); } fn foo(comptime a: usize, b: bool, args: ...) usize {