diff --git a/src/Sema.zig b/src/Sema.zig index d99ed3721e..c461c1a0b7 100644 --- a/src/Sema.zig +++ b/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); + 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); + // 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; - map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty }); + 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. diff --git a/test/behavior/union.zig b/test/behavior/union.zig index 4bf7bcf67a..2e29d26941 100644 --- a/test/behavior/union.zig +++ b/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);