Commit 90598b4631

Ben Noordhuis <info@bnoordhuis.nl>
2018-02-28 00:51:22
fix assert on self-referencing function ptr field
The construct `struct S { f: fn(S) void }` is not legal because structs are not copyable but it should not result in an ICE. Fixes #795.
1 parent 439621e
Changed files (2)
src/analyze.cpp
@@ -1670,6 +1670,9 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
     if (struct_type->data.structure.is_invalid)
         return;
 
+    if (struct_type->data.structure.zero_bits_loop_flag)
+      return;
+
     AstNode *decl_node = struct_type->data.structure.decl_node;
 
     if (struct_type->data.structure.embedded_in_current) {
@@ -1682,7 +1685,6 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
         return;
     }
 
-    assert(!struct_type->data.structure.zero_bits_loop_flag);
     assert(struct_type->data.structure.fields);
     assert(decl_node->type == NodeTypeContainerDecl);
 
test/compile_errors.zig
@@ -3090,4 +3090,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
     ,
         ".tmp_source.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",
         ".tmp_source.zig:3:5: note: field 'A' has type 'i32'");
+
+    cases.add("self-referencing function pointer field",
+        \\const S = struct {
+        \\    f: fn(_: S) void,
+        \\};
+        \\fn f(_: S) void {
+        \\}
+        \\export fn entry() void {
+        \\    var _ = S { .f = f };
+        \\}
+    ,
+        ".tmp_source.zig:4:9: error: type 'S' is not copyable; cannot pass by value");
 }