authorgravatar for xq@random-projects.netFelix "xq" Queißner <xq@random-projects.net> 2022-08-03 15:17:21+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-05 15:39:53+03:00
log263b5933d2fd63ae4052c7a29288968cbd8505bc
tree50c42d69970cddc4356a5a2de6c3e7bf56339703
parentfd3415ad5e007005f7d568c41967c563e2066e95

Makes std.meta.Tuple and std.meta.ArgsTuple generate a unique type instead of generating one per invocation.


1 files changed, 33 insertions(+), 18 deletions(-)

lib/std/meta.zig+33-18
...@@ -1024,28 +1024,13 @@ pub fn ArgsTuple(comptime Function: type) type {...@@ -1024,28 +1024,13 @@ pub fn ArgsTuple(comptime Function: type) type {
1024 if (function_info.is_var_args)1024 if (function_info.is_var_args)
1025 @compileError("Cannot create ArgsTuple for variadic function");1025 @compileError("Cannot create ArgsTuple for variadic function");
10261026
1027 var argument_field_list: [function_info.args.len]std.builtin.Type.StructField = undefined;1027 var argument_field_list: [function_info.args.len]type = undefined;
1028 inline for (function_info.args) |arg, i| {1028 inline for (function_info.args) |arg, i| {
1029 const T = arg.arg_type.?;1029 const T = arg.arg_type.?;
1030 @setEvalBranchQuota(10_000);1030 argument_field_list[i] = T;
1031 var num_buf: [128]u8 = undefined;
1032 argument_field_list[i] = .{
1033 .name = std.fmt.bufPrint(&num_buf, "{d}", .{i}) catch unreachable,
1034 .field_type = T,
1035 .default_value = null,
1036 .is_comptime = false,
1037 .alignment = if (@sizeOf(T) > 0) @alignOf(T) else 0,
1038 };
1039 }1031 }
10401032
1041 return @Type(.{1033 return CreateUniqueTuple(argument_field_list.len, argument_field_list);
1042 .Struct = .{
1043 .is_tuple = true,
1044 .layout = .Auto,
1045 .decls = &.{},
1046 .fields = &argument_field_list,
1047 },
1048 });
1049}1034}
10501035
1051/// For a given anonymous list of types, returns a new tuple type1036/// For a given anonymous list of types, returns a new tuple type
...@@ -1056,6 +1041,10 @@ pub fn ArgsTuple(comptime Function: type) type {...@@ -1056,6 +1041,10 @@ pub fn ArgsTuple(comptime Function: type) type {
1056/// - `Tuple(&[_]type {f32})` ⇒ `tuple { f32 }`1041/// - `Tuple(&[_]type {f32})` ⇒ `tuple { f32 }`
1057/// - `Tuple(&[_]type {f32,u32})` ⇒ `tuple { f32, u32 }`1042/// - `Tuple(&[_]type {f32,u32})` ⇒ `tuple { f32, u32 }`
1058pub fn Tuple(comptime types: []const type) type {1043pub fn Tuple(comptime types: []const type) type {
1044 return CreateUniqueTuple(types.len, types[0..types.len].*);
1045}
1046
1047fn CreateUniqueTuple(comptime N: comptime_int, comptime types: [N]type) type {
1059 var tuple_fields: [types.len]std.builtin.Type.StructField = undefined;1048 var tuple_fields: [types.len]std.builtin.Type.StructField = undefined;
1060 inline for (types) |T, i| {1049 inline for (types) |T, i| {
1061 @setEvalBranchQuota(10_000);1050 @setEvalBranchQuota(10_000);
...@@ -1118,6 +1107,32 @@ test "Tuple" {...@@ -1118,6 +1107,32 @@ test "Tuple" {
1118 TupleTester.assertTuple(.{ u32, f16, []const u8, void }, Tuple(&[_]type{ u32, f16, []const u8, void }));1107 TupleTester.assertTuple(.{ u32, f16, []const u8, void }, Tuple(&[_]type{ u32, f16, []const u8, void }));
1119}1108}
11201109
1110test "Tuple deduplication" {
1111 const T1 = std.meta.Tuple(&.{ u32, f32, i8 });
1112 const T2 = std.meta.Tuple(&.{ u32, f32, i8 });
1113 const T3 = std.meta.Tuple(&.{ u32, f32, i7 });
1114
1115 if (T1 != T2) {
1116 @compileError("std.meta.Tuple doesn't deduplicate tuple types.");
1117 }
1118 if (T1 == T3) {
1119 @compileError("std.meta.Tuple fails to generate different types.");
1120 }
1121}
1122
1123test "ArgsTuple forwarding" {
1124 const T1 = std.meta.Tuple(&.{ u32, f32, i8 });
1125 const T2 = std.meta.ArgsTuple(fn (u32, f32, i8) void);
1126 const T3 = std.meta.ArgsTuple(fn (u32, f32, i8) callconv(.C) noreturn);
1127
1128 if (T1 != T2) {
1129 @compileError("std.meta.ArgsTuple produces different types than std.meta.Tuple");
1130 }
1131 if (T1 != T3) {
1132 @compileError("std.meta.ArgsTuple produces different types for the same argument lists.");
1133 }
1134}
1135
1121/// TODO: https://github.com/ziglang/zig/issues/4251136/// TODO: https://github.com/ziglang/zig/issues/425
1122pub fn globalOption(comptime name: []const u8, comptime T: type) ?T {1137pub fn globalOption(comptime name: []const u8, comptime T: type) ?T {
1123 if (!@hasDecl(root, name))1138 if (!@hasDecl(root, name))