authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-10 15:22:17-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-10-10 15:22:17-04:00
logf42725c39bbbe5db13c1a1706db3f31aa0549307
tree08284761e667668a852e512a4a5ab193ded5288c
parentd1fd864da7859989828feb8be806634606cc761c
parentea45062d8227f9f9f1356c78eac5a0daa578f97e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #9925 from mattbork/uniondecl-fixes

stage2: astgen unionDecl fixes

4 files changed, 60 insertions(+), 4 deletions(-)

src/AstGen.zig+22-3
......@@ -4134,7 +4134,7 @@ fn unionDeclInner(
41344134 if (member.comptime_token) |comptime_token| {
41354135 return astgen.failTok(comptime_token, "union fields cannot be marked comptime", .{});
41364136 }
4137 try fields_data.ensureUnusedCapacity(gpa, if (node_tags[member.ast.type_expr] != .@"anytype") 4 else 3);
4137 try fields_data.ensureUnusedCapacity(gpa, 4);
41384138
41394139 const field_name = try astgen.identAsString(member.ast.name_token);
41404140 fields_data.appendAssumeCapacity(field_name);
......@@ -4149,9 +4149,14 @@ fn unionDeclInner(
41494149 (@as(u32, @boolToInt(have_value)) << 30) |
41504150 (@as(u32, @boolToInt(unused)) << 31);
41514151
4152 if (have_type and node_tags[member.ast.type_expr] != .@"anytype") {
4153 const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
4152 if (have_type) {
4153 const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype")
4154 .none
4155 else
4156 try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
41544157 fields_data.appendAssumeCapacity(@enumToInt(field_type));
4158 } else if (arg_inst == .none and !have_auto_enum) {
4159 return astgen.failNode(member_node, "union field missing type", .{});
41554160 }
41564161 if (have_align) {
41574162 const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr);
......@@ -4172,6 +4177,20 @@ fn unionDeclInner(
41724177 },
41734178 );
41744179 }
4180 if (!have_auto_enum) {
4181 return astgen.failNodeNotes(
4182 node,
4183 "explicitly valued tagged union requires inferred enum tag type",
4184 .{},
4185 &[_]u32{
4186 try astgen.errNoteNode(
4187 member.ast.value_expr,
4188 "tag value specified here",
4189 .{},
4190 ),
4191 },
4192 );
4193 }
41754194 const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr);
41764195 fields_data.appendAssumeCapacity(@enumToInt(tag_value));
41774196 }
src/Sema.zig+3-1
......@@ -12629,8 +12629,10 @@ fn semaUnionFields(
1262912629 set.putAssumeCapacity(field_name, {});
1263012630 }
1263112631
12632 const field_ty: Type = if (field_type_ref == .none)
12632 const field_ty: Type = if (!has_type)
1263312633 Type.initTag(.void)
12634 else if (field_type_ref == .none)
12635 Type.initTag(.noreturn)
1263412636 else
1263512637 // TODO: if we need to report an error here, use a source location
1263612638 // that points to this type expression rather than the union.
src/Zir.zig+1
......@@ -2686,6 +2686,7 @@ pub const Inst = struct {
26862686 /// 9. fields: { // for every fields_len
26872687 /// field_name: u32, // null terminated string index
26882688 /// field_type: Ref, // if corresponding bit is set
2689 /// - if none, means `anytype`.
26892690 /// align: Ref, // if corresponding bit is set
26902691 /// tag_value: Ref, // if corresponding bit is set
26912692 /// }
test/stage2/cbe.zig+34
......@@ -570,6 +570,40 @@ pub fn addCases(ctx: *TestContext) !void {
570570 , "");
571571 }
572572
573 {
574 var case = ctx.exeFromCompiledC("unions", .{});
575
576 case.addError(
577 \\const U = union {
578 \\ a: u32,
579 \\ b
580 \\};
581 , &.{
582 ":3:5: error: union field missing type",
583 });
584
585 case.addError(
586 \\const E = enum { a, b };
587 \\const U = union(E) {
588 \\ a: u32 = 1,
589 \\ b: f32 = 2,
590 \\};
591 , &.{
592 ":2:11: error: explicitly valued tagged union requires inferred enum tag type",
593 ":3:14: note: tag value specified here",
594 });
595
596 case.addError(
597 \\const U = union(enum) {
598 \\ a: u32 = 1,
599 \\ b: f32 = 2,
600 \\};
601 , &.{
602 ":1:11: error: explicitly valued tagged union missing integer tag type",
603 ":2:14: note: tag value specified here",
604 });
605 }
606
573607 {
574608 var case = ctx.exeFromCompiledC("enums", .{});
575609