Commit f9e4344bb5

Veikka Tuominen <git@vexu.eu>
2022-03-10 19:00:07
Sema: implement zirStructInit is_ref=true union
1 parent 673fafc
Changed files (3)
src/Sema.zig
@@ -3995,7 +3995,7 @@ pub fn analyzeExport(
     try mod.ensureDeclAnalyzed(exported_decl);
     // TODO run the same checks as we do for C ABI struct fields
     switch (exported_decl.ty.zigTypeTag()) {
-        .Fn, .Int, .Struct, .Array, .Float => {},
+        .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {},
         else => return sema.fail(block, src, "unable to export type '{}'", .{exported_decl.ty}),
     }
 
@@ -11674,18 +11674,25 @@ fn zirStructInit(
         const field_name = sema.code.nullTerminatedString(field_type_extra.name_start);
         const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
 
-        if (is_ref) {
-            return sema.fail(block, src, "TODO: Sema.zirStructInit is_ref=true union", .{});
-        }
-
         const init_inst = sema.resolveInst(item.data.init);
         if (try sema.resolveMaybeUndefVal(block, field_src, init_inst)) |val| {
             const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
-            return sema.addConstant(
+            return sema.addConstantMaybeRef(
+                block,
+                src,
                 resolved_ty,
                 try Value.Tag.@"union".create(sema.arena, .{ .tag = tag_val, .val = val }),
+                is_ref,
             );
         }
+
+        if (is_ref) {
+            const alloc = try block.addTy(.alloc, resolved_ty);
+            const field_ptr = try sema.unionFieldPtr(block, field_src, alloc, field_name, field_src, resolved_ty);
+            try sema.storePtr(block, src, field_ptr, init_inst);
+            return alloc;
+        }
+
         return sema.fail(block, src, "TODO: Sema.zirStructInit for runtime-known union values", .{});
     }
     unreachable;
test/behavior/export.zig
@@ -38,9 +38,6 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion) void {
 test "exporting enum type and value" {
     const S = struct {
         const E = enum(c_int) { one, two };
-        comptime {
-            @export(E, .{ .name = "E" });
-        }
         const e: E = .two;
         comptime {
             @export(e, .{ .name = "e" });
test/behavior.zig
@@ -57,6 +57,7 @@ test {
     _ = @import("behavior/bugs/5487.zig");
     _ = @import("behavior/bugs/6850.zig");
     _ = @import("behavior/bugs/7003.zig");
+    _ = @import("behavior/bugs/7047.zig");
     _ = @import("behavior/bugs/7250.zig");
     _ = @import("behavior/bugs/11100.zig");
     _ = @import("behavior/bugs/10970.zig");
@@ -142,12 +143,14 @@ test {
         if (builtin.zig_backend != .stage2_c) {
             // Tests that pass for stage1 and the llvm backend.
             _ = @import("behavior/atomics.zig");
+            _ = @import("behavior/export.zig");
             _ = @import("behavior/maximum_minimum.zig");
             _ = @import("behavior/popcount.zig");
             _ = @import("behavior/saturating_arithmetic.zig");
             _ = @import("behavior/widening.zig");
             _ = @import("behavior/bugs/2114.zig");
             _ = @import("behavior/bugs/3779.zig");
+            _ = @import("behavior/bugs/10147.zig");
             _ = @import("behavior/union_with_members.zig");
 
             if (builtin.zig_backend == .stage1) {
@@ -164,10 +167,7 @@ test {
                 _ = @import("behavior/bugs/6456.zig");
                 _ = @import("behavior/bugs/6781.zig");
                 _ = @import("behavior/bugs/7027.zig");
-                _ = @import("behavior/bugs/7047.zig");
-                _ = @import("behavior/bugs/10147.zig");
                 _ = @import("behavior/const_slice_child.zig");
-                _ = @import("behavior/export.zig");
                 _ = @import("behavior/select.zig");
                 _ = @import("behavior/shuffle.zig");
                 _ = @import("behavior/struct_contains_slice_of_itself.zig");