diff --git a/src/Sema.zig b/src/Sema.zig index 2b0ec08171..195a0ef274 100644 --- a/src/Sema.zig +++ b/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; diff --git a/test/behavior.zig b/test/behavior.zig index 32bb6382fa..871bd1c697 100644 --- a/test/behavior.zig +++ b/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"); diff --git a/test/behavior/export.zig b/test/behavior/export.zig index 9521c7cadb..5f8ccf02d4 100644 --- a/test/behavior/export.zig +++ b/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" });