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/Sema.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/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 4da7fabac6..5be0ef364f 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -712,8 +712,10 @@ fn analyzeBodyInner( .struct_init_ref => try sema.zirStructInit(block, inst, true), .struct_init_anon => try sema.zirStructInitAnon(block, inst, false), .struct_init_anon_ref => try sema.zirStructInitAnon(block, inst, true), - .array_init => try sema.zirArrayInit(block, inst, false), - .array_init_ref => try sema.zirArrayInit(block, inst, true), + .array_init => try sema.zirArrayInit(block, inst, false, false), + .array_init_sent => try sema.zirArrayInit(block, inst, false, true), + .array_init_ref => try sema.zirArrayInit(block, inst, true, false), + .array_init_sent_ref => try sema.zirArrayInit(block, inst, true, true), .array_init_anon => try sema.zirArrayInitAnon(block, inst, false), .array_init_anon_ref => try sema.zirArrayInitAnon(block, inst, true), .union_init => try sema.zirUnionInit(block, inst), @@ -11782,6 +11784,7 @@ fn zirArrayInit( block: *Block, inst: Zir.Inst.Index, is_ref: bool, + is_sent: bool, ) CompileError!Air.Inst.Ref { const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; @@ -11797,22 +11800,38 @@ fn zirArrayInit( for (args) |arg, i| resolved_args[i] = sema.resolveInst(arg); const elem_ty = sema.typeOf(resolved_args[0]); + const array_ty = blk: { + if (!is_sent) { + break :blk try Type.Tag.array.create(sema.arena, .{ + .len = resolved_args.len, + .elem_type = elem_ty, + }); + } - const array_ty = try Type.Tag.array.create(sema.arena, .{ - .len = resolved_args.len, - .elem_type = elem_ty, - }); + const sentinel_ref = resolved_args[resolved_args.len - 1]; + const val = try sema.resolveConstValue(block, src, sentinel_ref); + break :blk try Type.Tag.array_sentinel.create(sema.arena, .{ + .len = resolved_args.len - 1, + .sentinel = val, + .elem_type = elem_ty, + }); + }; + + const elems = if (!is_sent) + resolved_args + else + resolved_args[0 .. resolved_args.len - 1]; - const opt_runtime_src: ?LazySrcLoc = for (resolved_args) |arg| { + const opt_runtime_src: ?LazySrcLoc = for (elems) |arg| { const arg_src = src; // TODO better source location const comptime_known = try sema.isComptimeKnown(block, arg_src, arg); if (!comptime_known) break arg_src; } else null; const runtime_src = opt_runtime_src orelse { - const elem_vals = try sema.arena.alloc(Value, resolved_args.len); + const elem_vals = try sema.arena.alloc(Value, elems.len); - for (resolved_args) |arg, i| { + for (elems) |arg, i| { // We checked that all args are comptime above. elem_vals[i] = (sema.resolveMaybeUndefVal(block, src, arg) catch unreachable).?; } @@ -11839,7 +11858,7 @@ fn zirArrayInit( }); const elem_ptr_ty_ref = try sema.addType(elem_ptr_ty); - for (resolved_args) |arg, i| { + for (elems) |arg, i| { const index = try sema.addIntUnsigned(Type.usize, i); const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref); _ = try block.addBinOp(.store, elem_ptr, arg); @@ -11847,7 +11866,7 @@ fn zirArrayInit( return alloc; } - return block.addAggregateInit(array_ty, resolved_args); + return block.addAggregateInit(array_ty, elems); } fn zirArrayInitAnon( |
