authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-11 10:11:25+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-11 19:13:04-07:00
log7d3c5f207a375b800ad67294a0caa434b887b66f
treebdfb86a5d0ae527ce3a3593955c265168302a08b
parent0405698696acea924609ccd2e9c96064245f8df1

stage1: Avoid resolving type entry in [0]T

The logic was already there but this rule was only applied in some places, apply it in the remaining code paths. Closes #7058

3 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,7 +1453,12 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ
1453 case LazyValueIdArrayType: {1453 case LazyValueIdArrayType: {
1454 LazyValueArrayType *lazy_array_type =1454 LazyValueArrayType *lazy_array_type =
1455 reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);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 case LazyValueIdErrUnionType: {1463 case LazyValueIdErrUnionType: {
1459 LazyValueErrUnionType *lazy_err_union_type =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,8 +32970,13 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
32970 break;32970 break;
32971 }32971 }
3297232972
32973 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown)))32973 // Avoid resolving the type if the total length is zero.
32974 return err;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 }
3297532980
32976 ZigValue *sentinel_val = nullptr;32981 ZigValue *sentinel_val = nullptr;
32977 if (lazy_array_type->sentinel != nullptr) {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,3 +413,21 @@ test "sentinel element count towards the ABI size calculation" {
413 S.doTheTest();413 S.doTheTest();
414 comptime S.doTheTest();414 comptime S.doTheTest();
415}415}
416
417test "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}