authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-21 23:50:20-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-21 23:50:20-07:00
logc2a9a591f6f746c777800e4394ca0ee875be3688
treefaf0babedbd9bbbf8c107b3653422e7927de9524
parent9dc98fbabbd5e91622d2459ec6265a8dae2405b8

Sema: fix union auto-enum numbering


2 files changed, 22 insertions(+), 14 deletions(-)

src/Sema.zig+21-9
...@@ -17526,6 +17526,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -17526,6 +17526,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
17526 extra_index += bit_bags_count;17526 extra_index += bit_bags_count;
17527 var cur_bit_bag: u32 = undefined;17527 var cur_bit_bag: u32 = undefined;
17528 var field_i: u32 = 0;17528 var field_i: u32 = 0;
17529 var last_tag_val: ?Value = null;
17529 while (field_i < fields_len) : (field_i += 1) {17530 while (field_i < fields_len) : (field_i += 1) {
17530 if (field_i % fields_per_u32 == 0) {17531 if (field_i % fields_per_u32 == 0) {
17531 cur_bit_bag = zir.extra[bit_bag_index];17532 cur_bit_bag = zir.extra[bit_bag_index];
...@@ -17566,15 +17567,26 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -17566,15 +17567,26 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
17566 } else .none;17567 } else .none;
1756717568
17568 if (enum_value_map) |map| {17569 if (enum_value_map) |map| {
17569 const tag_src = src; // TODO better source location17570 if (tag_ref != .none) {
17570 const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src);17571 const tag_src = src; // TODO better source location
17571 const val = try sema.resolveConstValue(&block_scope, tag_src, coerced);17572 const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src);
1757217573 const val = try sema.resolveConstValue(&block_scope, tag_src, coerced);
17573 // This puts the memory into the union arena, not the enum arena, but17574 last_tag_val = val;
17574 // it is OK since they share the same lifetime.17575
17575 const copied_val = try val.copy(decl_arena_allocator);17576 // This puts the memory into the union arena, not the enum arena, but
1757617577 // it is OK since they share the same lifetime.
17577 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });17578 const copied_val = try val.copy(decl_arena_allocator);
17579 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
17580 } else {
17581 const val = if (last_tag_val) |val|
17582 try val.intAdd(Value.one, sema.arena)
17583 else
17584 Value.zero;
17585 last_tag_val = val;
17586
17587 const copied_val = try val.copy(decl_arena_allocator);
17588 map.putAssumeCapacityContext(copied_val, {}, .{ .ty = int_tag_ty });
17589 }
17578 }17590 }
1757917591
17580 // This string needs to outlive the ZIR code.17592 // This string needs to outlive the ZIR code.
test/behavior/union.zig+1-5
...@@ -495,7 +495,7 @@ test "tagged union with all void fields but a meaningful tag" {...@@ -495,7 +495,7 @@ test "tagged union with all void fields but a meaningful tag" {
495}495}
496496
497test "union(enum(u32)) with specified and unspecified tag values" {497test "union(enum(u32)) with specified and unspecified tag values" {
498 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO498 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
499499
500 comptime try expect(Tag(Tag(MultipleChoice2)) == u32);500 comptime try expect(Tag(Tag(MultipleChoice2)) == u32);
501 try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });501 try testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
...@@ -558,8 +558,6 @@ const PartialInstWithPayload = union(enum) {...@@ -558,8 +558,6 @@ const PartialInstWithPayload = union(enum) {
558};558};
559559
560test "union with only 1 field casted to its enum type which has enum value specified" {560test "union with only 1 field casted to its enum type which has enum value specified" {
561 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
562
563 const Literal = union(enum) {561 const Literal = union(enum) {
564 Number: f64,562 Number: f64,
565 Bool: bool,563 Bool: bool,
...@@ -640,8 +638,6 @@ fn Setter(attr: Attribute) type {...@@ -640,8 +638,6 @@ fn Setter(attr: Attribute) type {
640}638}
641639
642test "return union init with void payload" {640test "return union init with void payload" {
643 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
644
645 const S = struct {641 const S = struct {
646 fn entry() !void {642 fn entry() !void {
647 try expect(func().state == State.one);643 try expect(func().state == State.one);