Correct evaluation of optional type alignment
The lazy logic was too oversimplified and produced a different result than the one computed later causing all kinds of problems. Closes #4013master
parent
3f19bc5d01
commit
b91eaba38c
|
@ -1331,7 +1331,7 @@ start_over:
|
|||
zig_unreachable();
|
||||
}
|
||||
|
||||
Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_align) {
|
||||
Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align) {
|
||||
Error err;
|
||||
if (type_val->special != ConstValSpecialLazy) {
|
||||
assert(type_val->special == ConstValSpecialStatic);
|
||||
|
@ -1356,19 +1356,21 @@ Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_a
|
|||
*abi_align = g->builtin_types.entry_usize->abi_align;
|
||||
return ErrorNone;
|
||||
case LazyValueIdOptType: {
|
||||
LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(type_val->data.x_lazy);
|
||||
return type_val_resolve_abi_align(g, lazy_opt_type->payload_type->value, abi_align);
|
||||
if ((err = ir_resolve_lazy(g, nullptr, type_val)))
|
||||
return err;
|
||||
|
||||
return type_val_resolve_abi_align(g, source_node, type_val, abi_align);
|
||||
}
|
||||
case LazyValueIdArrayType: {
|
||||
LazyValueArrayType *lazy_array_type =
|
||||
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
|
||||
return type_val_resolve_abi_align(g, lazy_array_type->elem_type->value, abi_align);
|
||||
return type_val_resolve_abi_align(g, source_node, lazy_array_type->elem_type->value, abi_align);
|
||||
}
|
||||
case LazyValueIdErrUnionType: {
|
||||
LazyValueErrUnionType *lazy_err_union_type =
|
||||
reinterpret_cast<LazyValueErrUnionType *>(type_val->data.x_lazy);
|
||||
uint32_t payload_abi_align;
|
||||
if ((err = type_val_resolve_abi_align(g, lazy_err_union_type->payload_type->value,
|
||||
if ((err = type_val_resolve_abi_align(g, source_node, lazy_err_union_type->payload_type->value,
|
||||
&payload_abi_align)))
|
||||
{
|
||||
return err;
|
||||
|
@ -2335,7 +2337,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
|
|||
}
|
||||
field->align = field->type_entry->abi_align;
|
||||
} else {
|
||||
if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) {
|
||||
if ((err = type_val_resolve_abi_align(g, field->decl_node, field->type_val, &field->align))) {
|
||||
if (g->trace_err != nullptr) {
|
||||
g->trace_err = add_error_note(g, g->trace_err, field->decl_node,
|
||||
buf_create_from_str("while checking this field"));
|
||||
|
@ -2912,7 +2914,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
|
|||
} else if (packed) {
|
||||
field->align = 1;
|
||||
} else {
|
||||
if ((err = type_val_resolve_abi_align(g, field->type_val, &field->align))) {
|
||||
if ((err = type_val_resolve_abi_align(g, field->decl_node, field->type_val, &field->align))) {
|
||||
if (g->trace_err != nullptr) {
|
||||
g->trace_err = add_error_note(g, g->trace_err, field->decl_node,
|
||||
buf_create_from_str("while checking this field"));
|
||||
|
|
|
@ -260,7 +260,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
|
|||
void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
|
||||
bool fn_is_async(ZigFn *fn);
|
||||
|
||||
Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_align);
|
||||
Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align);
|
||||
Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,
|
||||
size_t *abi_size, size_t *size_in_bits);
|
||||
Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent_type,
|
||||
|
|
|
@ -29200,8 +29200,8 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
|
|||
}
|
||||
|
||||
uint32_t align_in_bytes;
|
||||
if ((err = type_val_resolve_abi_align(ira->codegen, lazy_align_of->target_type->value,
|
||||
&align_in_bytes)))
|
||||
if ((err = type_val_resolve_abi_align(ira->codegen, source_node,
|
||||
lazy_align_of->target_type->value, &align_in_bytes)))
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -145,3 +145,11 @@ test "coerce an anon struct literal to optional struct" {
|
|||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "optional with void type" {
|
||||
const Foo = struct {
|
||||
x: ?void,
|
||||
};
|
||||
var x = Foo{ .x = null };
|
||||
expect(x.x == null);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue