| ... | ... | @@ -1024,28 +1024,13 @@ pub fn ArgsTuple(comptime Function: type) type { |
| 1024 | 1024 | if (function_info.is_var_args) |
| 1025 | 1025 | @compileError("Cannot create ArgsTuple for variadic function"); |
| 1026 | 1026 | |
| 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 | 1028 | inline for (function_info.args) |arg, i| { |
| 1029 | 1029 | const T = arg.arg_type.?; |
| 1030 | | @setEvalBranchQuota(10_000); |
| 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 | | }; |
| 1030 | argument_field_list[i] = T; |
| 1039 | 1031 | } |
| 1040 | 1032 | |
| 1041 | | return @Type(.{ |
| 1042 | | .Struct = .{ |
| 1043 | | .is_tuple = true, |
| 1044 | | .layout = .Auto, |
| 1045 | | .decls = &.{}, |
| 1046 | | .fields = &argument_field_list, |
| 1047 | | }, |
| 1048 | | }); |
| 1033 | return CreateUniqueTuple(argument_field_list.len, argument_field_list); |
| 1049 | 1034 | } |
| 1050 | 1035 | |
| 1051 | 1036 | /// For a given anonymous list of types, returns a new tuple type |
| ... | ... | @@ -1056,6 +1041,10 @@ pub fn ArgsTuple(comptime Function: type) type { |
| 1056 | 1041 | /// - `Tuple(&[_]type {f32})` ⇒ `tuple { f32 }` |
| 1057 | 1042 | /// - `Tuple(&[_]type {f32,u32})` ⇒ `tuple { f32, u32 }` |
| 1058 | 1043 | pub fn Tuple(comptime types: []const type) type { |
| 1044 | return CreateUniqueTuple(types.len, types[0..types.len].*); |
| 1045 | } |
| 1046 | |
| 1047 | fn CreateUniqueTuple(comptime N: comptime_int, comptime types: [N]type) type { |
| 1059 | 1048 | var tuple_fields: [types.len]std.builtin.Type.StructField = undefined; |
| 1060 | 1049 | inline for (types) |T, i| { |
| 1061 | 1050 | @setEvalBranchQuota(10_000); |
| ... | ... | @@ -1118,6 +1107,32 @@ test "Tuple" { |
| 1118 | 1107 | TupleTester.assertTuple(.{ u32, f16, []const u8, void }, Tuple(&[_]type{ u32, f16, []const u8, void })); |
| 1119 | 1108 | } |
| 1120 | 1109 | |
| 1110 | test "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 | |
| 1123 | test "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 | 1136 | /// TODO: https://github.com/ziglang/zig/issues/425 |
| 1122 | 1137 | pub fn globalOption(comptime name: []const u8, comptime T: type) ?T { |
| 1123 | 1138 | if (!@hasDecl(root, name)) |