Commit 52c03de5c2

Andrew Kelley <andrew@ziglang.org>
2019-02-14 19:07:51
add missing compile error for OpaqueType inside structs/unions
closes #1862
1 parent e03c770
Changed files (2)
src/analyze.cpp
@@ -2679,6 +2679,13 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
                     buf_sprintf("enums, not structs, support field assignment"));
         }
 
+        if (field_type->id == ZigTypeIdOpaque) {
+            add_node_error(g, field_node->data.struct_field.type,
+                buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs"));
+            struct_type->data.structure.resolve_status = ResolveStatusInvalid;
+            continue;
+        }
+
         switch (type_requires_comptime(g, field_type)) {
             case ReqCompTimeYes:
                 struct_type->data.structure.requires_comptime = true;
@@ -2963,6 +2970,13 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
         }
         union_field->type_entry = field_type;
 
+        if (field_type->id == ZigTypeIdOpaque) {
+            add_node_error(g, field_node->data.struct_field.type,
+                buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in unions"));
+            union_type->data.unionation.is_invalid = true;
+            continue;
+        }
+
         switch (type_requires_comptime(g, field_type)) {
             case ReqCompTimeInvalid:
                 union_type->data.unionation.is_invalid = true;
test/compile_errors.zig
@@ -1,6 +1,27 @@
 const tests = @import("tests.zig");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.addTest(
+        "directly embedding opaque type in struct and union",
+        \\const O = @OpaqueType();
+        \\const Foo = struct {
+        \\    o: O,
+        \\};
+        \\const Bar = union {
+        \\    One: i32,
+        \\    Two: O,
+        \\};
+        \\export fn a() void {
+        \\    var foo: Foo = undefined;
+        \\}
+        \\export fn b() void {
+        \\    var bar: Bar = undefined;
+        \\}
+    ,
+        ".tmp_source.zig:3:8: error: opaque types have unknown size and therefore cannot be directly embedded in structs",
+        ".tmp_source.zig:7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions",
+    );
+
     cases.addTest(
         "implicit cast between C pointer and Zig pointer - bad const/align/child",
         \\export fn a() void {