diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-07 13:54:09 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-07 13:54:09 -0500 |
| commit | f59cbd89e349fb3002500cb2a1d69ca5e6063338 (patch) | |
| tree | fd60d586a95f7d23cce8ee671e36eee7a14ede68 /src/AstGen.zig | |
| parent | 8c32d989c995f8675f1824fb084245b833b26223 (diff) | |
| parent | 85b0a4a8fd8a56c07e0377b02d33753fe205fe41 (diff) | |
| download | zig-f59cbd89e349fb3002500cb2a1d69ca5e6063338.tar.gz zig-f59cbd89e349fb3002500cb2a1d69ca5e6063338.zip | |
Merge pull request #11077 from mitchellh/array-init-ty
stage2: sentinel-terminated array initialization
Diffstat (limited to 'src/AstGen.zig')
| -rw-r--r-- | src/AstGen.zig | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index fdd58dd948..d3ef670723 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1259,10 +1259,12 @@ fn arrayInitExpr( const types: struct { array: Zir.Inst.Ref, elem: Zir.Inst.Ref, + sentinel: Zir.Inst.Ref, } = inst: { if (array_init.ast.type_expr == 0) break :inst .{ .array = .none, .elem = .none, + .sentinel = .none, }; infer: { @@ -1282,6 +1284,7 @@ fn arrayInitExpr( break :inst .{ .array = array_type_inst, .elem = elem_type, + .sentinel = .none, }; } else { const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); @@ -1297,6 +1300,7 @@ fn arrayInitExpr( break :inst .{ .array = array_type_inst, .elem = elem_type, + .sentinel = sentinel, }; } } @@ -1307,6 +1311,7 @@ fn arrayInitExpr( break :inst .{ .array = array_type_inst, .elem = elem_type, + .sentinel = .none, }; }; @@ -1319,25 +1324,25 @@ fn arrayInitExpr( }, .ref => { if (types.array != .none) { - return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, .array_init_ref); + return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, true); } else { return arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon_ref); } }, .none => { if (types.array != .none) { - return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, .array_init); + return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, false); } else { return arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); } }, .ty, .coerced_ty => |ty_inst| { if (types.array != .none) { - const result = try arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, .array_init); + const result = try arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, types.elem, types.sentinel, false); return rvalue(gz, rl, result, node); } else { const elem_type = try gz.addUnNode(.elem_type, ty_inst, node); - return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, elem_type, .array_init); + return arrayInitExprRlTy(gz, scope, node, array_init.ast.elements, elem_type, types.sentinel, false); } }, .ptr => |ptr_inst| { @@ -1387,14 +1392,32 @@ fn arrayInitExprRlTy( node: Ast.Node.Index, elements: []const Ast.Node.Index, elem_ty_inst: Zir.Inst.Ref, - tag: Zir.Inst.Tag, + sentinel: Zir.Inst.Ref, + ref: bool, ) InnerError!Zir.Inst.Ref { const astgen = gz.astgen; + const info: struct { + len: usize, + tag: Zir.Inst.Tag, + } = blk: { + if (sentinel != .none) { + break :blk .{ + .len = elements.len + 1, + .tag = if (ref) .array_init_sent_ref else .array_init_sent, + }; + } else { + break :blk .{ + .len = elements.len, + .tag = if (ref) .array_init_ref else .array_init, + }; + } + }; + const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{ - .operands_len = @intCast(u32, elements.len), + .operands_len = @intCast(u32, info.len), }); - var extra_index = try reserveExtra(astgen, elements.len); + var extra_index = try reserveExtra(astgen, info.len); const elem_rl: ResultLoc = .{ .ty = elem_ty_inst }; for (elements) |elem_init| { @@ -1402,7 +1425,13 @@ fn arrayInitExprRlTy( astgen.extra.items[extra_index] = @enumToInt(elem_ref); extra_index += 1; } - return try gz.addPlNodePayloadIndex(tag, node, payload_index); + + if (sentinel != .none) { + astgen.extra.items[extra_index] = @enumToInt(sentinel); + extra_index += 1; + } + + return try gz.addPlNodePayloadIndex(info.tag, node, payload_index); } fn arrayInitExprRlPtr( @@ -2217,8 +2246,10 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .struct_init_anon_ref, .array_init, .array_init_anon, + .array_init_sent, .array_init_ref, .array_init_anon_ref, + .array_init_sent_ref, .union_init, .field_type, .field_type_ref, |
