Commit 44f8e6a534
Changed files (2)
src
stage1
test
stage1
behavior
src/stage1/analyze.cpp
@@ -5973,7 +5973,8 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
}
ZigType *field_type = resolve_struct_field_type(g, field);
assert(field_type != nullptr);
- result->data.x_struct.fields[i] = get_the_one_possible_value(g, field_type);
+ copy_const_val(g, result->data.x_struct.fields[i],
+ get_the_one_possible_value(g, field_type));
}
} else if (result->type->id == ZigTypeIdArray) {
// The elements array cannot be left unpopulated
@@ -5986,7 +5987,20 @@ ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry) {
ZigValue *elem_val = &result->data.x_array.data.s_none.elements[i];
copy_const_val(g, elem_val, get_the_one_possible_value(g, elem_type));
}
+ } else if (result->type->id == ZigTypeIdUnion) {
+ // The payload/tag fields cannot be left unpopulated
+ ZigType *union_type = result->type;
+ assert(union_type->data.unionation.src_field_count == 1);
+ TypeUnionField *only_field = &union_type->data.unionation.fields[0];
+ ZigType *field_type = resolve_union_field_type(g, only_field);
+ assert(field_type);
+ bigint_init_unsigned(&result->data.x_union.tag, 0);
+ result->data.x_union.payload = g->pass1_arena->create<ZigValue>();
+ copy_const_val(g, result->data.x_union.payload,
+ get_the_one_possible_value(g, field_type));
} else if (result->type->id == ZigTypeIdPointer) {
+ // Make sure nobody can modify the constant value
+ result->data.x_ptr.mut = ConstPtrMutComptimeConst;
result->data.x_ptr.special = ConstPtrSpecialRef;
result->data.x_ptr.data.ref.pointee = get_the_one_possible_value(g, result->type->data.pointer.child_type);
}
test/stage1/behavior/union.zig
@@ -713,3 +713,27 @@ test "switching on non exhaustive union" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "containers with single-field enums" {
+ const S = struct {
+ const A = union(enum) { f1 };
+ const B = union(enum) { f1: void };
+ const C = struct { a: A };
+ const D = struct { a: B };
+
+ fn doTheTest() void {
+ var array1 = [1]A{A{ .f1 = {} }};
+ var array2 = [1]B{B{ .f1 = {} }};
+ expect(array1[0] == .f1);
+ expect(array2[0] == .f1);
+
+ var struct1 = C{ .a = A{ .f1 = {} } };
+ var struct2 = D{ .a = B{ .f1 = {} } };
+ expect(struct1.a == .f1);
+ expect(struct2.a == .f1);
+ }
+ };
+
+ S.doTheTest();
+ comptime S.doTheTest();
+}