Skip to content

Commit

Permalink
fix @typeinfo not setting a field to comptime
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewrk committed May 15, 2018
1 parent 04bca58 commit 74b10c0
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 142 deletions.
1 change: 1 addition & 0 deletions src/ir.cpp
Expand Up @@ -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);
}
Expand Down
319 changes: 177 additions & 142 deletions test/cases/type_info.zig
Expand Up @@ -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,
};

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);
}
testErrorSet();
comptime testErrorSet();
}

fn testErrorSet() void {
const TestErrorSet = error {
First,
Second,
Third,
};

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);

const TestNoTagUnion = union {
Foo: void,
Bar: u32,
};

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 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);
}
testUnion();
comptime testUnion();
}

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 TestNoTagUnion = union {
Foo: void,
Bar: u32,
};

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 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 {
Expand All @@ -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));

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);
}
testFunction();
comptime testFunction();
}

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 {
Expand Down

0 comments on commit 74b10c0

Please sign in to comment.