aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-03-07 13:54:09 -0500
committerGitHub <noreply@github.com>2022-03-07 13:54:09 -0500
commitf59cbd89e349fb3002500cb2a1d69ca5e6063338 (patch)
treefd60d586a95f7d23cce8ee671e36eee7a14ede68 /src/Sema.zig
parent8c32d989c995f8675f1824fb084245b833b26223 (diff)
parent85b0a4a8fd8a56c07e0377b02d33753fe205fe41 (diff)
downloadzig-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.zig41
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(