From a1e78d0b0631885b95dfa80ab617818d1fd61277 Mon Sep 17 00:00:00 2001 From: Vexu Date: Thu, 16 Jul 2020 23:35:31 +0300 Subject: [PATCH] add is_tuple field to struct typeinfo part of #4335 --- lib/std/builtin.zig | 1 + lib/std/mem.zig | 5 ++--- src/ir.cpp | 8 +++++++- test/stage1/behavior/type_info.zig | 7 ++++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 5eafc4e409..499011eab9 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -246,6 +246,7 @@ pub const TypeInfo = union(enum) { layout: ContainerLayout, fields: []const StructField, decls: []const Declaration, + is_tuple: bool, }; /// This data structure is used by the Zig language code generation and diff --git a/lib/std/mem.zig b/lib/std/mem.zig index f4489a4867..ac7bde47c1 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -709,8 +709,7 @@ pub fn zeroInit(comptime T: type, init: anytype) T { .Struct => |init_info| { var value = std.mem.zeroes(T); - // typeInfo won't tell us if this is a tuple - if (comptime eql(u8, init_info.fields[0].name, "0")) { + if (init_info.is_tuple) { inline for (init_info.fields) |field, i| { @field(value, struct_info.fields[i].name) = @field(init, field.name); } @@ -785,7 +784,7 @@ test "zeroInit" { a: u8, }; - const c = zeroInit(Color, .{255, 255}); + const c = zeroInit(Color, .{ 255, 255 }); testing.expectEqual(Color{ .r = 255, .g = 255, diff --git a/src/ir.cpp b/src/ir.cpp index e162125fb4..d027badac1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -25546,7 +25546,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Struct", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3); + ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); result->data.x_struct.fields = fields; // layout: ContainerLayout @@ -25627,6 +25627,12 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy return err; } + // is_tuple: bool + ensure_field_index(result->type, "is_tuple", 3); + fields[3]->special = ConstValSpecialStatic; + fields[3]->type = ira->codegen->builtin_types.entry_bool; + fields[3]->data.x_bool = is_tuple(type_entry); + break; } case ZigTypeIdFn: diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index d4c8cec977..a79b3a1554 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -280,7 +280,7 @@ fn testFunction() void { expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct); } -extern fn foo(a: usize, b: bool, args: ...) usize; +extern fn foo(a: usize, b: bool, ...) usize; test "typeInfo with comptime parameter in struct fn def" { const S = struct { @@ -425,3 +425,8 @@ test "Declarations are returned in declaration order" { expect(std.mem.eql(u8, d[3].name, "d")); expect(std.mem.eql(u8, d[4].name, "e")); } + +test "Struct.is_tuple" { + expect(@typeInfo(@TypeOf(.{0})).Struct.is_tuple); + expect(!@typeInfo(@TypeOf(.{ .a = 0 })).Struct.is_tuple); +}