authorgravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-10-09 18:50:44-04:00
committergravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-10-09 20:39:50-04:00
logea45062d8227f9f9f1356c78eac5a0daa578f97e
tree7435b9cc3ffa9212671b8dfa1000915531524964
parent784be05a1abd94da96cce7c6381395f4f7b1ab5f

stage2: add astgen errors for untyped union fields and union field values without inferred tag type


2 files changed, 50 insertions(+), 0 deletions(-)

src/AstGen.zig+16
...@@ -4155,6 +4155,8 @@ fn unionDeclInner(...@@ -4155,6 +4155,8 @@ fn unionDeclInner(
4155 else4155 else
4156 try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);4156 try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
4157 fields_data.appendAssumeCapacity(@enumToInt(field_type));4157 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", .{});
4158 }4160 }
4159 if (have_align) {4161 if (have_align) {
4160 const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr);4162 const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr);
...@@ -4175,6 +4177,20 @@ fn unionDeclInner(...@@ -4175,6 +4177,20 @@ fn unionDeclInner(
4175 },4177 },
4176 );4178 );
4177 }4179 }
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 }
4178 const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr);4194 const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr);
4179 fields_data.appendAssumeCapacity(@enumToInt(tag_value));4195 fields_data.appendAssumeCapacity(@enumToInt(tag_value));
4180 }4196 }
test/stage2/cbe.zig+34
...@@ -570,6 +570,40 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -570,6 +570,40 @@ pub fn addCases(ctx: *TestContext) !void {
570 , "");570 , "");
571 }571 }
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
573 {607 {
574 var case = ctx.exeFromCompiledC("enums", .{});608 var case = ctx.exeFromCompiledC("enums", .{});
575609