Commit ea45062d82

Matthew Borkowski <matthew.h.borkowski@gmail.com>
2021-10-10 00:50:44
stage2: add astgen errors for untyped union fields and union field values without inferred tag type
1 parent 784be05
Changed files (2)
src
test
stage2
src/AstGen.zig
@@ -4155,6 +4155,8 @@ fn unionDeclInner(
             else
                 try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
             fields_data.appendAssumeCapacity(@enumToInt(field_type));
+        } else if (arg_inst == .none and !have_auto_enum) {
+            return astgen.failNode(member_node, "union field missing type", .{});
         }
         if (have_align) {
             const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr);
@@ -4175,6 +4177,20 @@ fn unionDeclInner(
                     },
                 );
             }
+            if (!have_auto_enum) {
+                return astgen.failNodeNotes(
+                    node,
+                    "explicitly valued tagged union requires inferred enum tag type",
+                    .{},
+                    &[_]u32{
+                        try astgen.errNoteNode(
+                            member.ast.value_expr,
+                            "tag value specified here",
+                            .{},
+                        ),
+                    },
+                );
+            }
             const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr);
             fields_data.appendAssumeCapacity(@enumToInt(tag_value));
         }
test/stage2/cbe.zig
@@ -570,6 +570,40 @@ pub fn addCases(ctx: *TestContext) !void {
         , "");
     }
 
+    {
+        var case = ctx.exeFromCompiledC("unions", .{});
+
+        case.addError(
+            \\const U = union {
+            \\    a: u32,
+            \\    b
+            \\};
+        , &.{
+            ":3:5: error: union field missing type",
+        });
+
+        case.addError(
+            \\const E = enum { a, b };
+            \\const U = union(E) {
+            \\    a: u32 = 1,
+            \\    b: f32 = 2,
+            \\};
+        , &.{
+            ":2:11: error: explicitly valued tagged union requires inferred enum tag type",
+            ":3:14: note: tag value specified here",
+        });
+
+        case.addError(
+            \\const U = union(enum) {
+            \\    a: u32 = 1,
+            \\    b: f32 = 2,
+            \\};
+        , &.{
+            ":1:11: error: explicitly valued tagged union missing integer tag type",
+            ":2:14: note: tag value specified here",
+        });
+    }
+
     {
         var case = ctx.exeFromCompiledC("enums", .{});