Commit 3d38feded9

Andrew Kelley <superjoe30@gmail.com>
2018-09-14 06:37:54
fix tagged union with all void payloads but meaningful tag
closes #1322
1 parent 1e03cf1
Changed files (3)
src/codegen.cpp
@@ -4715,7 +4715,6 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
 
 static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {
     ZigType *union_type = instruction->value->value.type;
-    assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
 
     ZigType *tag_type = union_type->data.unionation.tag_type;
     if (!type_has_bits(tag_type))
@@ -4725,6 +4724,7 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, Ir
     if (union_type->data.unionation.gen_field_count == 0)
         return union_val;
 
+    assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
     LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_val,
             union_type->data.unionation.gen_tag_index, "");
     ZigType *ptr_type = get_pointer_to_type(g, tag_type, false);
test/cases/bugs/1322.zig
@@ -0,0 +1,19 @@
+const std = @import("std");
+
+const B = union(enum) {
+    c: C,
+    None,
+};
+
+const A = struct {
+    b: B,
+};
+
+const C = struct {};
+
+test "tagged union with all void fields but a meaningful tag" {
+    var a: A = A{ .b = B{ .c = C{} } };
+    std.debug.assert(@TagType(B)(a.b) == @TagType(B).c);
+    a = A{ .b = B.None };
+    std.debug.assert(@TagType(B)(a.b) == @TagType(B).None);
+}
test/behavior.zig
@@ -10,6 +10,7 @@ comptime {
     _ = @import("cases/bool.zig");
     _ = @import("cases/bugs/1111.zig");
     _ = @import("cases/bugs/1277.zig");
+    _ = @import("cases/bugs/1322.zig");
     _ = @import("cases/bugs/1381.zig");
     _ = @import("cases/bugs/1421.zig");
     _ = @import("cases/bugs/1442.zig");