authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-07-07 12:28:51-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-08 10:19:17+03:00
log33a39c4b2b8a597c7d40d0c3ea0f5ca12a4636a8
treeeff4a0dd90e734758cb30c7440ba1b392bc2daec
parent3a03872af76652515e467c1f33d918ead2c0a6b0

stage2: Fix panic when printing AIR for tuple/anon struct types


2 files changed, 42 insertions(+), 54 deletions(-)

src/TypedValue.zig+30-54
...@@ -138,68 +138,33 @@ pub fn print(...@@ -138,68 +138,33 @@ pub fn print(
138 .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"),138 .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"),
139 .type_info_type => return writer.writeAll("std.builtin.Type"),139 .type_info_type => return writer.writeAll("std.builtin.Type"),
140140
141 .empty_struct_value => return writer.writeAll(".{}"),141 .empty_struct_value, .aggregate => {
142 .aggregate => {
143 if (level == 0) {142 if (level == 0) {
144 return writer.writeAll(".{ ... }");143 return writer.writeAll(".{ ... }");
145 }144 }
146 const vals = val.castTag(.aggregate).?.data;145 if (ty.zigTypeTag() == .Struct) {
147 if (ty.castTag(.anon_struct)) |anon_struct| {146 try writer.writeAll(".{");
148 const field_names = anon_struct.data.names;147 const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items);
149 const types = anon_struct.data.types;
150 const max_len = std.math.min(types.len, max_aggregate_items);
151148
152 var i: u32 = 0;149 var i: u32 = 0;
153 while (i < max_len) : (i += 1) {150 while (i < max_len) : (i += 1) {
154 if (i != 0) try writer.writeAll(", ");151 if (i != 0) try writer.writeAll(", ");
155 try writer.print(".{s} = ", .{field_names[i]});152 switch (ty.tag()) {
153 .anon_struct, .@"struct" => try writer.print(".{s} = ", .{ty.structFieldName(i)}),
154 else => {},
155 }
156 try print(.{156 try print(.{
157 .ty = types[i],157 .ty = ty.structFieldType(i),
158 .val = vals[i],158 .val = ty.structFieldValueComptime(i) orelse b: {
159 const vals = val.castTag(.aggregate).?.data;
160 break :b vals[i];
161 },
159 }, writer, level - 1, mod);162 }, writer, level - 1, mod);
160 }163 }
161 if (types.len > max_aggregate_items) {164 if (ty.structFieldCount() > max_aggregate_items) {
162 try writer.writeAll(", ...");165 try writer.writeAll(", ...");
163 }166 }
164 return writer.writeAll(" }");167 return writer.writeAll("}");
165 } else if (ty.isTuple()) {
166 const fields = ty.tupleFields();
167 const max_len = std.math.min(fields.types.len, max_aggregate_items);
168
169 var i: u32 = 0;
170 while (i < max_len) : (i += 1) {
171 if (i != 0) try writer.writeAll(", ");
172 try print(.{
173 .ty = fields.types[i],
174 .val = vals[i],
175 }, writer, level - 1, mod);
176 }
177 if (fields.types.len > max_aggregate_items) {
178 try writer.writeAll(", ...");
179 }
180 return writer.writeAll(" }");
181 } else if (ty.zigTypeTag() == .Struct) {
182 try writer.writeAll(".{ ");
183 const struct_fields = ty.structFields();
184 const len = struct_fields.count();
185 const max_len = std.math.min(len, max_aggregate_items);
186
187 const field_names = struct_fields.keys();
188 const fields = struct_fields.values();
189
190 var i: u32 = 0;
191 while (i < max_len) : (i += 1) {
192 if (i != 0) try writer.writeAll(", ");
193 try writer.print(".{s} = ", .{field_names[i]});
194 try print(.{
195 .ty = fields[i].ty,
196 .val = vals[i],
197 }, writer, level - 1, mod);
198 }
199 if (len > max_aggregate_items) {
200 try writer.writeAll(", ...");
201 }
202 return writer.writeAll(" }");
203 } else {168 } else {
204 try writer.writeAll(".{ ");169 try writer.writeAll(".{ ");
205 const elem_ty = ty.elemType2();170 const elem_ty = ty.elemType2();
...@@ -211,7 +176,7 @@ pub fn print(...@@ -211,7 +176,7 @@ pub fn print(
211 if (i != 0) try writer.writeAll(", ");176 if (i != 0) try writer.writeAll(", ");
212 try print(.{177 try print(.{
213 .ty = elem_ty,178 .ty = elem_ty,
214 .val = vals[i],179 .val = val.castTag(.aggregate).?.data[i],
215 }, writer, level - 1, mod);180 }, writer, level - 1, mod);
216 }181 }
217 if (len > max_aggregate_items) {182 if (len > max_aggregate_items) {
...@@ -335,12 +300,23 @@ pub fn print(...@@ -335,12 +300,23 @@ pub fn print(
335 }300 }
336301
337 if (field_ptr.container_ty.zigTypeTag() == .Struct) {302 if (field_ptr.container_ty.zigTypeTag() == .Struct) {
338 const field_name = field_ptr.container_ty.structFields().keys()[field_ptr.field_index];303 switch (field_ptr.container_ty.tag()) {
339 return writer.print(".{s}", .{field_name});304 .tuple => return writer.print(".@\"{d}\"", .{field_ptr.field_index}),
305 else => {
306 const field_name = field_ptr.container_ty.structFieldName(field_ptr.field_index);
307 return writer.print(".{s}", .{field_name});
308 },
309 }
340 } else if (field_ptr.container_ty.zigTypeTag() == .Union) {310 } else if (field_ptr.container_ty.zigTypeTag() == .Union) {
341 const field_name = field_ptr.container_ty.unionFields().keys()[field_ptr.field_index];311 const field_name = field_ptr.container_ty.unionFields().keys()[field_ptr.field_index];
342 return writer.print(".{s}", .{field_name});312 return writer.print(".{s}", .{field_name});
343 } else unreachable;313 } else if (field_ptr.container_ty.isSlice()) {
314 switch (field_ptr.field_index) {
315 Value.Payload.Slice.ptr_index => return writer.writeAll(".ptr"),
316 Value.Payload.Slice.len_index => return writer.writeAll(".len"),
317 else => unreachable,
318 }
319 }
344 },320 },
345 .empty_array => return writer.writeAll(".{}"),321 .empty_array => return writer.writeAll(".{}"),
346 .enum_literal => return writer.print(".{}", .{std.zig.fmtId(val.castTag(.enum_literal).?.data)}),322 .enum_literal => return writer.print(".{}", .{std.zig.fmtId(val.castTag(.enum_literal).?.data)}),
src/type.zig+12
...@@ -5372,6 +5372,18 @@ pub const Type = extern union {...@@ -5372,6 +5372,18 @@ pub const Type = extern union {
5372 }5372 }
5373 }5373 }
53745374
5375 pub fn structFieldName(ty: Type, field_index: usize) []const u8 {
5376 switch (ty.tag()) {
5377 .@"struct" => {
5378 const struct_obj = ty.castTag(.@"struct").?.data;
5379 assert(struct_obj.haveFieldTypes());
5380 return struct_obj.fields.keys()[field_index];
5381 },
5382 .anon_struct => return ty.castTag(.anon_struct).?.data.names[field_index],
5383 else => unreachable,
5384 }
5385 }
5386
5375 pub fn structFieldCount(ty: Type) usize {5387 pub fn structFieldCount(ty: Type) usize {
5376 switch (ty.tag()) {5388 switch (ty.tag()) {
5377 .@"struct" => {5389 .@"struct" => {