Commit c2a9a591f6
src/Sema.zig
@@ -17526,6 +17526,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
extra_index += bit_bags_count;
var cur_bit_bag: u32 = undefined;
var field_i: u32 = 0;
+ var last_tag_val: ?Value = null;
while (field_i < fields_len) : (field_i += 1) {
if (field_i % fields_per_u32 == 0) {
cur_bit_bag = zir.extra[bit_bag_index];
@@ -17566,15 +17567,26 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
} else .none;
if (enum_value_map) |map| {
- const tag_src = src; // TODO better source location
- const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src);
- const val = try sema.resolveConstValue(&block_scope, tag_src, coerced);
-
- // This puts the memory into the union arena, not the enum arena, but
- // it is OK since they share the same lifetime.
- const copied_val = try val.copy(decl_arena_allocator);
-
- map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
+ if (tag_ref != .none) {
+ const tag_src = src; // TODO better source location
+ const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src);
+ const val = try sema.resolveConstValue(&block_scope, tag_src, coerced);
+ last_tag_val = val;
+
+ // This puts the memory into the union arena, not the enum arena, but
+ // it is OK since they share the same lifetime.
+ const copied_val = try val.copy(decl_arena_allocator);
+ map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
+ } else {
+ const val = if (last_tag_val) |val|
+ try val.intAdd(Value.one, sema.arena)
+ else
+ Value.zero;
+ last_tag_val = val;
+
+ const copied_val = try val.copy(decl_arena_allocator);
+ map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
+ }
}
// This string needs to outlive the ZIR code.
test/behavior/union.zig
@@ -495,7 +495,7 @@ test "tagged union with all void fields but a meaningful tag" {
}
test "union(enum(u32)) with specified and unspecified tag values" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
comptime try expect(Tag(Tag(MultipleChoice2)) == u32);
try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
@@ -558,8 +558,6 @@ const PartialInstWithPayload = union(enum) {
};
test "union with only 1 field casted to its enum type which has enum value specified" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
const Literal = union(enum) {
Number: f64,
Bool: bool,
@@ -640,8 +638,6 @@ fn Setter(attr: Attribute) type {
}
test "return union init with void payload" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
const S = struct {
fn entry() !void {
try expect(func().state == State.one);