diff options
| author | Felix "xq" Queißner <xq@random-projects.net> | 2022-08-03 15:17:21 +0200 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-08-05 15:39:53 +0300 |
| commit | 263b5933d2fd63ae4052c7a29288968cbd8505bc (patch) | |
| tree | 50c42d69970cddc4356a5a2de6c3e7bf56339703 /lib/std/meta.zig | |
| parent | fd3415ad5e007005f7d568c41967c563e2066e95 (diff) | |
| download | zig-263b5933d2fd63ae4052c7a29288968cbd8505bc.tar.gz zig-263b5933d2fd63ae4052c7a29288968cbd8505bc.zip | |
Makes std.meta.Tuple and std.meta.ArgsTuple generate a unique type instead of generating one per invocation.
Diffstat (limited to 'lib/std/meta.zig')
| -rw-r--r-- | lib/std/meta.zig | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/lib/std/meta.zig b/lib/std/meta.zig index c6717ad1c0..d5006bf81f 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -1024,28 +1024,13 @@ pub fn ArgsTuple(comptime Function: type) type { if (function_info.is_var_args) @compileError("Cannot create ArgsTuple for variadic function"); - var argument_field_list: [function_info.args.len]std.builtin.Type.StructField = undefined; + var argument_field_list: [function_info.args.len]type = undefined; inline for (function_info.args) |arg, i| { const T = arg.arg_type.?; - @setEvalBranchQuota(10_000); - var num_buf: [128]u8 = undefined; - argument_field_list[i] = .{ - .name = std.fmt.bufPrint(&num_buf, "{d}", .{i}) catch unreachable, - .field_type = T, - .default_value = null, - .is_comptime = false, - .alignment = if (@sizeOf(T) > 0) @alignOf(T) else 0, - }; + argument_field_list[i] = T; } - return @Type(.{ - .Struct = .{ - .is_tuple = true, - .layout = .Auto, - .decls = &.{}, - .fields = &argument_field_list, - }, - }); + return CreateUniqueTuple(argument_field_list.len, argument_field_list); } /// For a given anonymous list of types, returns a new tuple type @@ -1056,6 +1041,10 @@ pub fn ArgsTuple(comptime Function: type) type { /// - `Tuple(&[_]type {f32})` ⇒ `tuple { f32 }` /// - `Tuple(&[_]type {f32,u32})` ⇒ `tuple { f32, u32 }` pub fn Tuple(comptime types: []const type) type { + return CreateUniqueTuple(types.len, types[0..types.len].*); +} + +fn CreateUniqueTuple(comptime N: comptime_int, comptime types: [N]type) type { var tuple_fields: [types.len]std.builtin.Type.StructField = undefined; inline for (types) |T, i| { @setEvalBranchQuota(10_000); @@ -1118,6 +1107,32 @@ test "Tuple" { TupleTester.assertTuple(.{ u32, f16, []const u8, void }, Tuple(&[_]type{ u32, f16, []const u8, void })); } +test "Tuple deduplication" { + const T1 = std.meta.Tuple(&.{ u32, f32, i8 }); + const T2 = std.meta.Tuple(&.{ u32, f32, i8 }); + const T3 = std.meta.Tuple(&.{ u32, f32, i7 }); + + if (T1 != T2) { + @compileError("std.meta.Tuple doesn't deduplicate tuple types."); + } + if (T1 == T3) { + @compileError("std.meta.Tuple fails to generate different types."); + } +} + +test "ArgsTuple forwarding" { + const T1 = std.meta.Tuple(&.{ u32, f32, i8 }); + const T2 = std.meta.ArgsTuple(fn (u32, f32, i8) void); + const T3 = std.meta.ArgsTuple(fn (u32, f32, i8) callconv(.C) noreturn); + + if (T1 != T2) { + @compileError("std.meta.ArgsTuple produces different types than std.meta.Tuple"); + } + if (T1 != T3) { + @compileError("std.meta.ArgsTuple produces different types for the same argument lists."); + } +} + /// TODO: https://github.com/ziglang/zig/issues/425 pub fn globalOption(comptime name: []const u8, comptime T: type) ?T { if (!@hasDecl(root, name)) |
