authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-08 21:59:43-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-12-08 21:59:43-05:00
log5c67f9ce7a4d9f5aedbe8cfba1f361922701a144
tree27572b3b063b780f3b82970c04f94981a017409d
parent225ed65ed2cc88fce54660250feaeb44e45943fa
parentee9fc54cd032b6ac0fcaa422aa9c2826fa370bfa
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13827 from Vexu/fix-ci

TypedValue: fix handling of tuples represented as empty_struct_value

6 files changed, 39 insertions(+), 50 deletions(-)

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