From f0b1b74d214169a72cf5ae28d88637f20100bcad Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 11 Nov 2020 10:11:25 +0100 Subject: [PATCH] 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 --- src/stage1/analyze.cpp | 7 ++++++- src/stage1/ir.cpp | 9 +++++++-- test/stage1/behavior/array.zig | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index 2fe4410027..9e0c0d5df8 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -1453,7 +1453,12 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ case LazyValueIdArrayType: { LazyValueArrayType *lazy_array_type = reinterpret_cast(type_val->data.x_lazy); - return type_val_resolve_abi_align(g, source_node, lazy_array_type->elem_type->value, abi_align); + + if (lazy_array_type->length + (lazy_array_type->sentinel != nullptr) != 0) + return type_val_resolve_abi_align(g, source_node, lazy_array_type->elem_type->value, abi_align); + + *abi_align = 0; + return ErrorNone; } case LazyValueIdErrUnionType: { LazyValueErrUnionType *lazy_err_union_type = diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 91fb81c24a..a984664cf8 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -32970,8 +32970,13 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { break; } - if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) - return err; + // Avoid resolving the type if the total length is zero. + // Matches the logic in get_array_type and in the lazy alignment + // resolution routine. + if (lazy_array_type->length + (lazy_array_type->sentinel != nullptr) != 0) { + if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) + return err; + } ZigValue *sentinel_val = nullptr; if (lazy_array_type->sentinel != nullptr) { diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 9e1d2cbac4..01592d151f 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -413,3 +413,21 @@ test "sentinel element count towards the ABI size calculation" { S.doTheTest(); comptime S.doTheTest(); } + +test "zero-sized array with recursive type definition" { + const U = struct { + fn foo(comptime T: type, comptime n: usize) type { + return struct { + s: [n]T, + x: usize = n, + }; + } + }; + + const S = struct { + list: U.foo(@This(), 0), + }; + + var t: S = .{ .list = .{ .s = undefined } }; + expectEqual(@as(usize, 0), t.list.x); +}