fix union init with void payload
all std lib tests passing now
This commit is contained in:
parent
3021e5ca67
commit
c61e0a078c
|
@ -5001,12 +5001,9 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
|
|||
field_val->type = wanted_type->data.structure.fields[i].type_entry;
|
||||
assert(field_val->type);
|
||||
init_const_undefined(g, field_val);
|
||||
ConstParent *parent = get_const_val_parent(g, field_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdStruct;
|
||||
parent->data.p_struct.struct_val = const_val;
|
||||
parent->data.p_struct.field_index = i;
|
||||
}
|
||||
field_val->parent.id = ConstParentIdStruct;
|
||||
field_val->parent.data.p_struct.struct_val = const_val;
|
||||
field_val->parent.data.p_struct.field_index = i;
|
||||
}
|
||||
} else {
|
||||
const_val->special = ConstValSpecialUndef;
|
||||
|
@ -5842,11 +5839,6 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
|
|||
zig_unreachable();
|
||||
}
|
||||
|
||||
// Deprecated. Reference the parent field directly.
|
||||
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
|
||||
return &value->parent;
|
||||
}
|
||||
|
||||
static const ZigTypeId all_type_ids[] = {
|
||||
ZigTypeIdMetaType,
|
||||
ZigTypeIdVoid,
|
||||
|
|
|
@ -180,7 +180,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
|
|||
ConstExprValue *create_const_vals(size_t count);
|
||||
|
||||
ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
|
||||
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
|
||||
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
|
||||
void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);
|
||||
|
||||
|
|
|
@ -3873,8 +3873,20 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
|
|||
|
||||
TypeUnionField *field = instruction->field;
|
||||
|
||||
if (!type_has_bits(field->type_entry))
|
||||
if (!type_has_bits(field->type_entry)) {
|
||||
if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {
|
||||
return nullptr;
|
||||
}
|
||||
if (instruction->initializing) {
|
||||
LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
|
||||
LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
|
||||
union_type->data.unionation.gen_tag_index, "");
|
||||
LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
|
||||
&field->enum_field->value);
|
||||
gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
|
||||
LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0);
|
||||
|
|
18
src/ir.cpp
18
src/ir.cpp
|
@ -17425,11 +17425,9 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
|
|||
ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];
|
||||
field_val->special = ConstValSpecialUndef;
|
||||
field_val->type = struct_type->data.structure.fields[i].type_entry;
|
||||
ConstParent *parent = get_const_val_parent(ira->codegen, field_val);
|
||||
assert(parent != nullptr);
|
||||
parent->id = ConstParentIdStruct;
|
||||
parent->data.p_struct.struct_val = struct_val;
|
||||
parent->data.p_struct.field_index = i;
|
||||
field_val->parent.id = ConstParentIdStruct;
|
||||
field_val->parent.data.p_struct.struct_val = struct_val;
|
||||
field_val->parent.data.p_struct.field_index = i;
|
||||
}
|
||||
}
|
||||
IrInstruction *result;
|
||||
|
@ -17507,11 +17505,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
|
|||
ConstExprValue *payload_val = create_const_vals(1);
|
||||
payload_val->special = ConstValSpecialUndef;
|
||||
payload_val->type = field->type_entry;
|
||||
ConstParent *parent = get_const_val_parent(ira->codegen, payload_val);
|
||||
if (parent != nullptr) {
|
||||
parent->id = ConstParentIdUnion;
|
||||
parent->data.p_union.union_val = union_val;
|
||||
}
|
||||
payload_val->parent.id = ConstParentIdUnion;
|
||||
payload_val->parent.data.p_union.union_val = union_val;
|
||||
|
||||
union_val->special = ConstValSpecialStatic;
|
||||
bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value);
|
||||
|
@ -25289,7 +25284,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
|
|||
case IrInstructionIdReturnPtr:
|
||||
case IrInstructionIdTypeOf:
|
||||
case IrInstructionIdStructFieldPtr:
|
||||
case IrInstructionIdUnionFieldPtr:
|
||||
case IrInstructionIdArrayType:
|
||||
case IrInstructionIdPromiseType:
|
||||
case IrInstructionIdSliceType:
|
||||
|
@ -25389,6 +25383,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
|
|||
}
|
||||
case IrInstructionIdUnwrapErrCode:
|
||||
return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing;
|
||||
case IrInstructionIdUnionFieldPtr:
|
||||
return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing;
|
||||
case IrInstructionIdErrWrapPayload:
|
||||
return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
|
||||
case IrInstructionIdErrWrapCode:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// TODO remove `use` keyword eventually
|
||||
// TODO remove `use` keyword eventually: https://github.com/ziglang/zig/issues/2591
|
||||
test "zig fmt: change use to usingnamespace" {
|
||||
try testTransform(
|
||||
\\use @import("std");
|
||||
|
@ -105,7 +105,6 @@ test "zig fmt: linksection" {
|
|||
}
|
||||
|
||||
test "zig fmt: correctly move doc comments on struct fields" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testTransform(
|
||||
\\pub const section_64 = extern struct {
|
||||
\\ sectname: [16]u8, /// name of this section
|
||||
|
@ -917,7 +916,6 @@ test "zig fmt: statements with empty line between" {
|
|||
}
|
||||
|
||||
test "zig fmt: ptr deref operator and unwrap optional operator" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\const a = b.*;
|
||||
\\const a = b.?;
|
||||
|
@ -1020,7 +1018,6 @@ test "zig fmt: same-line comment after a statement" {
|
|||
}
|
||||
|
||||
test "zig fmt: same-line comment after var decl in struct" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\pub const vfs_cap_data = extern struct {
|
||||
\\ const Data = struct {}; // when on disk.
|
||||
|
@ -1030,7 +1027,6 @@ test "zig fmt: same-line comment after var decl in struct" {
|
|||
}
|
||||
|
||||
test "zig fmt: same-line comment after field decl" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\pub const dirent = extern struct {
|
||||
\\ d_name: u8,
|
||||
|
@ -1106,7 +1102,6 @@ test "zig fmt: line comments in struct initializer" {
|
|||
}
|
||||
|
||||
test "zig fmt: first line comment in struct initializer" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\pub async fn acquire(self: *Self) HeldLock {
|
||||
\\ return HeldLock{
|
||||
|
@ -1120,7 +1115,6 @@ test "zig fmt: first line comment in struct initializer" {
|
|||
}
|
||||
|
||||
test "zig fmt: doc comments before struct field" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\pub const Allocator = struct {
|
||||
\\ /// Allocate byte_count bytes and return them in a slice, with the
|
||||
|
@ -1218,7 +1212,6 @@ test "zig fmt: comments before switch prong" {
|
|||
}
|
||||
|
||||
test "zig fmt: comments before var decl in struct" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\pub const vfs_cap_data = extern struct {
|
||||
\\ // All of these are mandated as little endian
|
||||
|
@ -1609,7 +1602,6 @@ test "zig fmt: indexing" {
|
|||
}
|
||||
|
||||
test "zig fmt: struct declaration" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\const S = struct {
|
||||
\\ const Self = @This();
|
||||
|
@ -1641,7 +1633,6 @@ test "zig fmt: struct declaration" {
|
|||
}
|
||||
|
||||
test "zig fmt: enum declaration" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\const E = enum {
|
||||
\\ Ok,
|
||||
|
@ -1670,7 +1661,6 @@ test "zig fmt: enum declaration" {
|
|||
}
|
||||
|
||||
test "zig fmt: union declaration" {
|
||||
if (true) return error.SkipZigTest; // TODO
|
||||
try testCanonical(
|
||||
\\const U = union {
|
||||
\\ Int: u8,
|
||||
|
|
|
@ -402,3 +402,23 @@ test "comptime union field value equality" {
|
|||
expect(a0 != a1);
|
||||
expect(b0 != b1);
|
||||
}
|
||||
|
||||
test "return union init with void payload" {
|
||||
const S = struct {
|
||||
fn entry() void {
|
||||
expect(func().state == State.one);
|
||||
}
|
||||
const Outer = union(enum) {
|
||||
state: State,
|
||||
};
|
||||
const State = union(enum) {
|
||||
one: void,
|
||||
two: u32,
|
||||
};
|
||||
fn func() Outer {
|
||||
return Outer{ .state = State{ .one = {} }};
|
||||
}
|
||||
};
|
||||
S.entry();
|
||||
comptime S.entry();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user