| author | |
| committer | |
| log | 7d3c5f207a375b800ad67294a0caa434b887b66f |
| tree | bdfb86a5d0ae527ce3a3593955c265168302a08b |
| parent | 0405698696acea924609ccd2e9c96064245f8df1 |
The logic was already there but this rule was only applied in some
places, apply it in the remaining code paths.
Closes #70583 files changed, 31 insertions(+), 3 deletions(-)
src/stage1/analyze.cpp+6-1| ... | ... | @@ -1453,7 +1453,12 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ |
| 1453 | 1453 | case LazyValueIdArrayType: { |
| 1454 | 1454 | LazyValueArrayType *lazy_array_type = |
| 1455 | 1455 | reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy); |
| 1456 | return type_val_resolve_abi_align(g, source_node, lazy_array_type->elem_type->value, abi_align); | |
| 1456 | ||
| 1457 | if (lazy_array_type->length + (lazy_array_type->sentinel != nullptr) != 0) | |
| 1458 | return type_val_resolve_abi_align(g, source_node, lazy_array_type->elem_type->value, abi_align); | |
| 1459 | ||
| 1460 | *abi_align = 0; | |
| 1461 | return ErrorNone; | |
| 1457 | 1462 | } |
| 1458 | 1463 | case LazyValueIdErrUnionType: { |
| 1459 | 1464 | LazyValueErrUnionType *lazy_err_union_type = |
src/stage1/ir.cpp+7-2| ... | ... | @@ -32970,8 +32970,13 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { |
| 32970 | 32970 | break; |
| 32971 | 32971 | } |
| 32972 | 32972 | |
| 32973 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) | |
| 32974 | return err; | |
| 32973 | // Avoid resolving the type if the total length is zero. | |
| 32974 | // Matches the logic in get_array_type and in the lazy alignment | |
| 32975 | // resolution routine. | |
| 32976 | if (lazy_array_type->length + (lazy_array_type->sentinel != nullptr) != 0) { | |
| 32977 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) | |
| 32978 | return err; | |
| 32979 | } | |
| 32975 | 32980 | |
| 32976 | 32981 | ZigValue *sentinel_val = nullptr; |
| 32977 | 32982 | if (lazy_array_type->sentinel != nullptr) { |
test/stage1/behavior/array.zig+18| ... | ... | @@ -413,3 +413,21 @@ test "sentinel element count towards the ABI size calculation" { |
| 413 | 413 | S.doTheTest(); |
| 414 | 414 | comptime S.doTheTest(); |
| 415 | 415 | } |
| 416 | ||
| 417 | test "zero-sized array with recursive type definition" { | |
| 418 | const U = struct { | |
| 419 | fn foo(comptime T: type, comptime n: usize) type { | |
| 420 | return struct { | |
| 421 | s: [n]T, | |
| 422 | x: usize = n, | |
| 423 | }; | |
| 424 | } | |
| 425 | }; | |
| 426 | ||
| 427 | const S = struct { | |
| 428 | list: U.foo(@This(), 0), | |
| 429 | }; | |
| 430 | ||
| 431 | var t: S = .{ .list = .{ .s = undefined } }; | |
| 432 | expectEqual(@as(usize, 0), t.list.x); | |
| 433 | } |