| author | |
| committer | |
| log | 5c67f9ce7a4d9f5aedbe8cfba1f361922701a144 |
| tree | 27572b3b063b780f3b82970c04f94981a017409d |
| parent | 225ed65ed2cc88fce54660250feaeb44e45943fa |
| parent | ee9fc54cd032b6ac0fcaa422aa9c2826fa370bfa |
| signature | Signed by PGP key 4AEE18F83AFDEB23 |
TypedValue: fix handling of tuples represented as empty_struct_value6 files changed, 39 insertions(+), 50 deletions(-)
lib/std/comptime_string_map.zig+20-29| ... | ... | @@ -5,9 +5,8 @@ const mem = std.mem; |
| 5 | 5 | /// Works by separating the keys by length at comptime and only checking strings of |
| 6 | 6 | /// equal length at runtime. |
| 7 | 7 | /// |
| 8 | /// `kvs` expects a list literal containing list literals or an array/slice of structs | |
| 9 | /// where `.@"0"` is the `[]const u8` key and `.@"1"` is the associated value of type `V`. | |
| 10 | /// TODO: https://github.com/ziglang/zig/issues/4335 | |
| 8 | /// `kvs_list` expects a list of `struct { []const u8, V }` (key-value pair) tuples. | |
| 9 | /// You can pass `struct { []const u8 }` (only keys) tuples if `V` is `void`. | |
| 11 | 10 | pub fn ComptimeStringMap(comptime V: type, comptime kvs_list: anytype) type { |
| 12 | 11 | const precomputed = comptime blk: { |
| 13 | 12 | @setEvalBranchQuota(2000); |
| ... | ... | @@ -97,32 +96,26 @@ test "ComptimeStringMap list literal of list literals" { |
| 97 | 96 | } |
| 98 | 97 | |
| 99 | 98 | test "ComptimeStringMap array of structs" { |
| 100 | const KV = struct { | |
| 101 | @"0": []const u8, | |
| 102 | @"1": TestEnum, | |
| 103 | }; | |
| 99 | const KV = struct { []const u8, TestEnum }; | |
| 104 | 100 | const map = ComptimeStringMap(TestEnum, [_]KV{ |
| 105 | .{ .@"0" = "these", .@"1" = .D }, | |
| 106 | .{ .@"0" = "have", .@"1" = .A }, | |
| 107 | .{ .@"0" = "nothing", .@"1" = .B }, | |
| 108 | .{ .@"0" = "incommon", .@"1" = .C }, | |
| 109 | .{ .@"0" = "samelen", .@"1" = .E }, | |
| 101 | .{ "these", .D }, | |
| 102 | .{ "have", .A }, | |
| 103 | .{ "nothing", .B }, | |
| 104 | .{ "incommon", .C }, | |
| 105 | .{ "samelen", .E }, | |
| 110 | 106 | }); |
| 111 | 107 | |
| 112 | 108 | try testMap(map); |
| 113 | 109 | } |
| 114 | 110 | |
| 115 | 111 | test "ComptimeStringMap slice of structs" { |
| 116 | const KV = struct { | |
| 117 | @"0": []const u8, | |
| 118 | @"1": TestEnum, | |
| 119 | }; | |
| 112 | const KV = struct { []const u8, TestEnum }; | |
| 120 | 113 | const slice: []const KV = &[_]KV{ |
| 121 | .{ .@"0" = "these", .@"1" = .D }, | |
| 122 | .{ .@"0" = "have", .@"1" = .A }, | |
| 123 | .{ .@"0" = "nothing", .@"1" = .B }, | |
| 124 | .{ .@"0" = "incommon", .@"1" = .C }, | |
| 125 | .{ .@"0" = "samelen", .@"1" = .E }, | |
| 114 | .{ "these", .D }, | |
| 115 | .{ "have", .A }, | |
| 116 | .{ "nothing", .B }, | |
| 117 | .{ "incommon", .C }, | |
| 118 | .{ "samelen", .E }, | |
| 126 | 119 | }; |
| 127 | 120 | const map = ComptimeStringMap(TestEnum, slice); |
| 128 | 121 | |
| ... | ... | @@ -141,15 +134,13 @@ fn testMap(comptime map: anytype) !void { |
| 141 | 134 | } |
| 142 | 135 | |
| 143 | 136 | test "ComptimeStringMap void value type, slice of structs" { |
| 144 | const KV = struct { | |
| 145 | @"0": []const u8, | |
| 146 | }; | |
| 137 | const KV = struct { []const u8 }; | |
| 147 | 138 | const slice: []const KV = &[_]KV{ |
| 148 | .{ .@"0" = "these" }, | |
| 149 | .{ .@"0" = "have" }, | |
| 150 | .{ .@"0" = "nothing" }, | |
| 151 | .{ .@"0" = "incommon" }, | |
| 152 | .{ .@"0" = "samelen" }, | |
| 139 | .{"these"}, | |
| 140 | .{"have"}, | |
| 141 | .{"nothing"}, | |
| 142 | .{"incommon"}, | |
| 143 | .{"samelen"}, | |
| 153 | 144 | }; |
| 154 | 145 | const map = ComptimeStringMap(void, slice); |
| 155 | 146 |
lib/std/meta.zig+2-8| ... | ... | @@ -115,16 +115,10 @@ pub fn stringToEnum(comptime T: type, str: []const u8) ?T { |
| 115 | 115 | // - https://github.com/ziglang/zig/issues/3863 |
| 116 | 116 | if (@typeInfo(T).Enum.fields.len <= 100) { |
| 117 | 117 | const kvs = comptime build_kvs: { |
| 118 | // In order to generate an array of structs that play nice with anonymous | |
| 119 | // list literals, we need to give them "0" and "1" field names. | |
| 120 | // TODO https://github.com/ziglang/zig/issues/4335 | |
| 121 | const EnumKV = struct { | |
| 122 | @"0": []const u8, | |
| 123 | @"1": T, | |
| 124 | }; | |
| 118 | const EnumKV = struct { []const u8, T }; | |
| 125 | 119 | var kvs_array: [@typeInfo(T).Enum.fields.len]EnumKV = undefined; |
| 126 | 120 | inline for (@typeInfo(T).Enum.fields) |enumField, i| { |
| 127 | kvs_array[i] = .{ .@"0" = enumField.name, .@"1" = @field(T, enumField.name) }; | |
| 121 | kvs_array[i] = .{ enumField.name, @field(T, enumField.name) }; | |
| 128 | 122 | } |
| 129 | 123 | break :build_kvs kvs_array[0..]; |
| 130 | 124 | }; |
src/TypedValue.zig+4-12| ... | ... | @@ -142,12 +142,10 @@ pub fn print( |
| 142 | 142 | .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"), |
| 143 | 143 | .type_info_type => return writer.writeAll("std.builtin.Type"), |
| 144 | 144 | |
| 145 | .empty_struct_value => return writer.writeAll(".{}"), | |
| 146 | .aggregate => { | |
| 145 | .empty_struct_value, .aggregate => { | |
| 147 | 146 | if (level == 0) { |
| 148 | 147 | return writer.writeAll(".{ ... }"); |
| 149 | 148 | } |
| 150 | const values = val.castTag(.aggregate).?; | |
| 151 | 149 | if (ty.zigTypeTag() == .Struct) { |
| 152 | 150 | try writer.writeAll(".{"); |
| 153 | 151 | const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items); |
| ... | ... | @@ -161,13 +159,7 @@ pub fn print( |
| 161 | 159 | } |
| 162 | 160 | try print(.{ |
| 163 | 161 | .ty = ty.structFieldType(i), |
| 164 | .val = switch (ty.containerLayout()) { | |
| 165 | .Packed => values.data[i], | |
| 166 | else => ty.structFieldValueComptime(i) orelse b: { | |
| 167 | const vals = values.data; | |
| 168 | break :b vals[i]; | |
| 169 | }, | |
| 170 | }, | |
| 162 | .val = val.fieldValue(ty, i), | |
| 171 | 163 | }, writer, level - 1, mod); |
| 172 | 164 | } |
| 173 | 165 | if (ty.structFieldCount() > max_aggregate_items) { |
| ... | ... | @@ -184,7 +176,7 @@ pub fn print( |
| 184 | 176 | |
| 185 | 177 | var i: u32 = 0; |
| 186 | 178 | while (i < max_len) : (i += 1) { |
| 187 | buf[i] = std.math.cast(u8, values.data[i].toUnsignedInt(target)) orelse break :str; | |
| 179 | buf[i] = std.math.cast(u8, val.fieldValue(ty, i).toUnsignedInt(target)) orelse break :str; | |
| 188 | 180 | } |
| 189 | 181 | |
| 190 | 182 | const truncated = if (len > max_string_len) " (truncated)" else ""; |
| ... | ... | @@ -199,7 +191,7 @@ pub fn print( |
| 199 | 191 | if (i != 0) try writer.writeAll(", "); |
| 200 | 192 | try print(.{ |
| 201 | 193 | .ty = elem_ty, |
| 202 | .val = values.data[i], | |
| 194 | .val = val.fieldValue(ty, i), | |
| 203 | 195 | }, writer, level - 1, mod); |
| 204 | 196 | } |
| 205 | 197 | if (len > max_aggregate_items) { |
src/type.zig-1| ... | ... | @@ -5670,7 +5670,6 @@ pub const Type = extern union { |
| 5670 | 5670 | switch (ty.tag()) { |
| 5671 | 5671 | .@"struct" => { |
| 5672 | 5672 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 5673 | assert(struct_obj.layout != .Packed); | |
| 5674 | 5673 | const field = struct_obj.fields.values()[index]; |
| 5675 | 5674 | if (field.is_comptime) { |
| 5676 | 5675 | return field.default_val; |
test/behavior.zig+1| ... | ... | @@ -120,6 +120,7 @@ test { |
| 120 | 120 | _ = @import("behavior/bugs/13435.zig"); |
| 121 | 121 | _ = @import("behavior/bugs/13664.zig"); |
| 122 | 122 | _ = @import("behavior/bugs/13714.zig"); |
| 123 | _ = @import("behavior/bugs/13785.zig"); | |
| 123 | 124 | _ = @import("behavior/byteswap.zig"); |
| 124 | 125 | _ = @import("behavior/byval_arg_var.zig"); |
| 125 | 126 | _ = @import("behavior/call.zig"); |
test/behavior/bugs/13785.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | ||
| 4 | const S = packed struct { a: u0 = 0 }; | |
| 5 | test { | |
| 6 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 7 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 8 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 9 | ||
| 10 | var a: u8 = 0; | |
| 11 | try std.io.null_writer.print("\n{} {}\n", .{ a, S{} }); | |
| 12 | } |