aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2024-02-06 01:55:22 +0000
committermlugg <mlugg@mlugg.co.uk>2024-03-06 21:26:37 +0000
commita6ca20b9a1dfc7b6e8d004cb166c0714bb8db2db (patch)
tree8ecc7aae4a07f9e5a2fe1d2f2acfe0f40f5ea673 /src/Sema.zig
parent90ab8ea9e681a4ffac0b4dc500e3ec489014e12f (diff)
downloadzig-a6ca20b9a1dfc7b6e8d004cb166c0714bb8db2db.tar.gz
zig-a6ca20b9a1dfc7b6e8d004cb166c0714bb8db2db.zip
compiler: change representation of closures
This changes the representation of closures in Zir and Sema. Rather than a pair of instructions `closure_capture` and `closure_get`, the system now works as follows: * Each ZIR type declaration (`struct_decl` etc) contains a list of captures in the form of ZIR indices (or, for efficiency, direct references to parent captures). This is an ordered list; indexes into it are used to refer to captured values. * The `extended(closure_get)` ZIR instruction refers to a value in this list via a 16-bit index (limiting this index to 16 bits allows us to store this in `extended`). * `Module.Namespace` has a new field `captures` which contains the list of values captured in a given namespace. This is initialized based on the ZIR capture list whenever a type declaration is analyzed. This change eliminates `CaptureScope` from semantic analysis, which is a nice simplification; but the main motivation here is that this change is a prerequisite for #18816.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig231
1 files changed, 114 insertions, 117 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index bf0aacabe5..b4a8445230 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -155,7 +155,6 @@ const Namespace = Module.Namespace;
const CompileError = Module.CompileError;
const SemaError = Module.SemaError;
const Decl = Module.Decl;
-const CaptureScope = Module.CaptureScope;
const LazySrcLoc = std.zig.LazySrcLoc;
const RangeSet = @import("RangeSet.zig");
const target_util = @import("target.zig");
@@ -331,8 +330,6 @@ pub const Block = struct {
/// used to add a `func_instance` into the `InternPool`.
params: std.MultiArrayList(Param) = .{},
- wip_capture_scope: CaptureScope.Index,
-
label: ?*Label = null,
inlining: ?*Inlining,
/// If runtime_index is not 0 then one of these is guaranteed to be non null.
@@ -475,7 +472,6 @@ pub const Block = struct {
.src_decl = parent.src_decl,
.namespace = parent.namespace,
.instructions = .{},
- .wip_capture_scope = parent.wip_capture_scope,
.label = null,
.inlining = parent.inlining,
.is_comptime = parent.is_comptime,
@@ -974,12 +970,6 @@ fn analyzeBodyInner(
try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);
- // Most of the time, we don't need to construct a new capture scope for a
- // block. However, successive iterations of comptime loops can capture
- // different values for the same Zir.Inst.Index, so in those cases, we will
- // have to create nested capture scopes; see the `.repeat` case below.
- const parent_capture_scope = block.wip_capture_scope;
-
const mod = sema.mod;
const map = &sema.inst_map;
const tags = sema.code.instructions.items(.tag);
@@ -1028,7 +1018,6 @@ fn analyzeBodyInner(
.c_import => try sema.zirCImport(block, inst),
.call => try sema.zirCall(block, inst, .direct),
.field_call => try sema.zirCall(block, inst, .field),
- .closure_get => try sema.zirClosureGet(block, inst),
.cmp_lt => try sema.zirCmp(block, inst, .lt),
.cmp_lte => try sema.zirCmp(block, inst, .lte),
.cmp_eq => try sema.zirCmpEq(block, inst, .eq, Air.Inst.Tag.fromCmpOp(.eq, block.float_mode == .Optimized)),
@@ -1275,6 +1264,7 @@ fn analyzeBodyInner(
.work_group_size => try sema.zirWorkItem( block, extended, extended.opcode),
.work_group_id => try sema.zirWorkItem( block, extended, extended.opcode),
.in_comptime => try sema.zirInComptime( block),
+ .closure_get => try sema.zirClosureGet( block, extended),
// zig fmt: on
.fence => {
@@ -1453,11 +1443,6 @@ fn analyzeBodyInner(
i += 1;
continue;
},
- .closure_capture => {
- try sema.zirClosureCapture(block, inst);
- i += 1;
- continue;
- },
.memcpy => {
try sema.zirMemcpy(block, inst);
i += 1;
@@ -1534,11 +1519,6 @@ fn analyzeBodyInner(
// Send comptime control flow back to the beginning of this block.
const src = LazySrcLoc.nodeOffset(datas[@intFromEnum(inst)].node);
try sema.emitBackwardBranch(block, src);
-
- // We need to construct new capture scopes for the next loop iteration so it
- // can capture values without clobbering the earlier iteration's captures.
- block.wip_capture_scope = try mod.createCaptureScope(parent_capture_scope);
-
i = 0;
continue;
} else {
@@ -1552,11 +1532,6 @@ fn analyzeBodyInner(
// Send comptime control flow back to the beginning of this block.
const src = LazySrcLoc.nodeOffset(datas[@intFromEnum(inst)].node);
try sema.emitBackwardBranch(block, src);
-
- // We need to construct new capture scopes for the next loop iteration so it
- // can capture values without clobbering the earlier iteration's captures.
- block.wip_capture_scope = try mod.createCaptureScope(parent_capture_scope);
-
i = 0;
continue;
},
@@ -1855,10 +1830,6 @@ fn analyzeBodyInner(
map.putAssumeCapacity(inst, air_inst);
i += 1;
}
-
- // We may have overwritten the capture scope due to a `repeat` instruction where
- // the body had a capture; restore it now.
- block.wip_capture_scope = parent_capture_scope;
}
pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
@@ -2698,10 +2669,41 @@ fn analyzeAsInt(
return (try val.getUnsignedIntAdvanced(mod, sema)).?;
}
+/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
+/// resolves this into a list of `Namespace.CaptureValue` allocated by `gpa`.
+/// Caller owns returned memory.
+fn getCaptures(sema: *Sema, parent_namespace: ?InternPool.NamespaceIndex, extra_index: usize, captures_len: u32) ![]Namespace.CaptureValue {
+ const gpa = sema.gpa;
+ const parent_captures: []const Namespace.CaptureValue = if (parent_namespace) |p| parent: {
+ break :parent sema.mod.namespacePtr(p).captures;
+ } else &.{};
+
+ const captures = try gpa.alloc(Namespace.CaptureValue, captures_len);
+ errdefer gpa.free(captures);
+
+ for (sema.code.extra[extra_index..][0..captures_len], captures) |raw, *capture| {
+ const zir_capture: Zir.Inst.Capture = @enumFromInt(raw);
+ capture.* = switch (zir_capture.unwrap()) {
+ .inst => |inst| Namespace.CaptureValue.wrap(capture: {
+ const air_ref = try sema.resolveInst(inst.toRef());
+ if (try sema.resolveValue(air_ref)) |val| {
+ break :capture .{ .@"comptime" = val.toIntern() };
+ }
+ break :capture .{ .runtime = sema.typeOf(air_ref).toIntern() };
+ }),
+ .nested => |parent_idx| parent_captures[parent_idx],
+ };
+ }
+
+ return captures;
+}
+
pub fn getStructType(
sema: *Sema,
decl: InternPool.DeclIndex,
namespace: InternPool.NamespaceIndex,
+ /// The direct parent Namespace for resolving nested capture values.
+ parent_namespace: ?InternPool.NamespaceIndex,
tracked_inst: InternPool.TrackedInst.Index,
) !InternPool.Index {
const mod = sema.mod;
@@ -2713,6 +2715,11 @@ pub fn getStructType(
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
+ const captures_len = if (small.has_captures_len) blk: {
+ const captures_len = sema.code.extra[extra_index];
+ extra_index += 1;
+ break :blk captures_len;
+ } else 0;
const fields_len = if (small.has_fields_len) blk: {
const fields_len = sema.code.extra[extra_index];
extra_index += 1;
@@ -2724,6 +2731,9 @@ pub fn getStructType(
break :blk decls_len;
} else 0;
+ mod.namespacePtr(namespace).captures = try sema.getCaptures(parent_namespace, extra_index, captures_len);
+ extra_index += captures_len;
+
if (small.has_backing_int) {
const backing_int_body_len = sema.code.extra[extra_index];
extra_index += 1; // backing_int_body_len
@@ -2791,12 +2801,13 @@ fn zirStructDecl(
.parent = block.namespace.toOptional(),
.decl_index = new_decl_index,
.file_scope = block.getFileScope(mod),
+ .captures = &.{}, // Will be set by `getStructType`
});
errdefer mod.destroyNamespace(new_namespace_index);
const struct_ty = ty: {
const tracked_inst = try ip.trackZir(mod.gpa, block.getFileScope(mod), inst);
- const ty = try sema.getStructType(new_decl_index, new_namespace_index, tracked_inst);
+ const ty = try sema.getStructType(new_decl_index, new_namespace_index, block.namespace, tracked_inst);
if (sema.builtin_type_target_index != .none) {
ip.resolveBuiltinType(sema.builtin_type_target_index, ty);
break :ty sema.builtin_type_target_index;
@@ -2827,10 +2838,9 @@ fn createAnonymousDeclTypeNamed(
const ip = &mod.intern_pool;
const gpa = sema.gpa;
const namespace = block.namespace;
- const src_scope = block.wip_capture_scope;
const src_decl = mod.declPtr(block.src_decl);
const src_node = src_decl.relativeToNodeIndex(src.node_offset.x);
- const new_decl_index = try mod.allocateNewDecl(namespace, src_node, src_scope);
+ const new_decl_index = try mod.allocateNewDecl(namespace, src_node);
errdefer mod.destroyDecl(new_decl_index);
switch (name_strategy) {
@@ -2935,6 +2945,12 @@ fn zirEnumDecl(
break :blk tag_type_ref;
} else .none;
+ const captures_len = if (small.has_captures_len) blk: {
+ const captures_len = sema.code.extra[extra_index];
+ extra_index += 1;
+ break :blk captures_len;
+ } else 0;
+
const body_len = if (small.has_body_len) blk: {
const body_len = sema.code.extra[extra_index];
extra_index += 1;
@@ -2974,10 +2990,14 @@ fn zirEnumDecl(
);
}
+ const captures = try sema.getCaptures(block.namespace, extra_index, captures_len);
+ extra_index += captures_len;
+
const new_namespace_index = try mod.createNamespace(.{
.parent = block.namespace.toOptional(),
.decl_index = new_decl_index,
.file_scope = block.getFileScope(mod),
+ .captures = captures,
});
errdefer if (!done) mod.destroyNamespace(new_namespace_index);
@@ -3054,7 +3074,6 @@ fn zirEnumDecl(
.sema = sema,
.src_decl = new_decl_index,
.namespace = new_namespace_index,
- .wip_capture_scope = try mod.createCaptureScope(new_decl.src_scope),
.instructions = .{},
.inlining = null,
.is_comptime = true,
@@ -3197,6 +3216,11 @@ fn zirUnionDecl(
const src = extra.data.src();
extra_index += @intFromBool(small.has_tag_type);
+ const captures_len = if (small.has_captures_len) blk: {
+ const captures_len = sema.code.extra[extra_index];
+ extra_index += 1;
+ break :blk captures_len;
+ } else 0;
extra_index += @intFromBool(small.has_body_len);
const fields_len = if (small.has_fields_len) blk: {
const fields_len = sema.code.extra[extra_index];
@@ -3230,10 +3254,14 @@ fn zirUnionDecl(
);
}
+ const captures = try sema.getCaptures(block.namespace, extra_index, captures_len);
+ extra_index += captures_len;
+
const new_namespace_index = try mod.createNamespace(.{
.parent = block.namespace.toOptional(),
.decl_index = new_decl_index,
.file_scope = block.getFileScope(mod),
+ .captures = captures,
});
errdefer mod.destroyNamespace(new_namespace_index);
@@ -3300,6 +3328,12 @@ fn zirOpaqueDecl(
const src = extra.data.src();
+ const captures_len = if (small.has_captures_len) blk: {
+ const captures_len = sema.code.extra[extra_index];
+ extra_index += 1;
+ break :blk captures_len;
+ } else 0;
+
const decls_len = if (small.has_decls_len) blk: {
const decls_len = sema.code.extra[extra_index];
extra_index += 1;
@@ -3326,10 +3360,14 @@ fn zirOpaqueDecl(
);
}
+ const captures = try sema.getCaptures(block.namespace, extra_index, captures_len);
+ extra_index += captures_len;
+
const new_namespace_index = try mod.createNamespace(.{
.parent = block.namespace.toOptional(),
.decl_index = new_decl_index,
.file_scope = block.getFileScope(mod),
+ .captures = captures,
});
errdefer mod.destroyNamespace(new_namespace_index);
@@ -5780,7 +5818,6 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
.sema = sema,
.src_decl = parent_block.src_decl,
.namespace = parent_block.namespace,
- .wip_capture_scope = parent_block.wip_capture_scope,
.instructions = .{},
.inlining = parent_block.inlining,
.is_comptime = true,
@@ -5900,7 +5937,6 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_compt
.sema = sema,
.src_decl = parent_block.src_decl,
.namespace = parent_block.namespace,
- .wip_capture_scope = parent_block.wip_capture_scope,
.instructions = .{},
.label = &label,
.inlining = parent_block.inlining,
@@ -7515,7 +7551,6 @@ fn analyzeCall(
.sema = sema,
.src_decl = module_fn.owner_decl,
.namespace = fn_owner_decl.src_namespace,
- .wip_capture_scope = try mod.createCaptureScope(fn_owner_decl.src_scope),
.instructions = .{},
.label = null,
.inlining = &inlining,
@@ -8036,7 +8071,6 @@ fn instantiateGenericCall(
.sema = &child_sema,
.src_decl = generic_owner_func.owner_decl,
.namespace = namespace_index,
- .wip_capture_scope = try mod.createCaptureScope(fn_owner_decl.src_scope),
.instructions = .{},
.inlining = null,
.is_comptime = true,
@@ -11409,7 +11443,6 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
.sema = sema,
.src_decl = block.src_decl,
.namespace = block.namespace,
- .wip_capture_scope = block.wip_capture_scope,
.instructions = .{},
.label = &label,
.inlining = block.inlining,
@@ -12117,7 +12150,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
.sema = sema,
.src_decl = block.src_decl,
.namespace = block.namespace,
- .wip_capture_scope = block.wip_capture_scope,
.instructions = .{},
.label = &label,
.inlining = block.inlining,
@@ -12281,7 +12313,6 @@ fn analyzeSwitchRuntimeBlock(
extra_index += info.body_len;
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = try mod.createCaptureScope(child_block.wip_capture_scope);
const item = case_vals.items[scalar_i];
// `item` is already guaranteed to be constant known.
@@ -12339,7 +12370,6 @@ fn analyzeSwitchRuntimeBlock(
case_val_idx += items_len;
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = child_block.wip_capture_scope;
// Generate all possible cases as scalar prongs.
if (info.is_inline) {
@@ -12371,7 +12401,6 @@ fn analyzeSwitchRuntimeBlock(
const item_ref = Air.internedToRef(item.toIntern());
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = child_block.wip_capture_scope;
if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {
error.NeededSourceLocation => {
@@ -12411,7 +12440,6 @@ fn analyzeSwitchRuntimeBlock(
cases_len += 1;
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = child_block.wip_capture_scope;
const analyze_body = if (union_originally) blk: {
const item_val = sema.resolveConstDefinedValue(block, .unneeded, item, undefined) catch unreachable;
@@ -12557,7 +12585,6 @@ fn analyzeSwitchRuntimeBlock(
defer gpa.free(cond_body);
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = try mod.createCaptureScope(child_block.wip_capture_scope);
const body = sema.code.bodySlice(extra_index, info.body_len);
extra_index += info.body_len;
@@ -12618,7 +12645,6 @@ fn analyzeSwitchRuntimeBlock(
const item_ref = Air.internedToRef(item_val.toIntern());
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = child_block.wip_capture_scope;
const analyze_body = if (union_originally) blk: {
const field_ty = maybe_union_ty.unionFieldType(item_val, mod).?;
@@ -12669,7 +12695,6 @@ fn analyzeSwitchRuntimeBlock(
const item_ref = Air.internedToRef(item_val);
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = child_block.wip_capture_scope;
if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src);
emit_bb = true;
@@ -12700,7 +12725,6 @@ fn analyzeSwitchRuntimeBlock(
const item_ref = Air.internedToRef(cur);
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = child_block.wip_capture_scope;
if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src);
emit_bb = true;
@@ -12728,7 +12752,6 @@ fn analyzeSwitchRuntimeBlock(
cases_len += 1;
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = child_block.wip_capture_scope;
if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src);
emit_bb = true;
@@ -12754,7 +12777,6 @@ fn analyzeSwitchRuntimeBlock(
cases_len += 1;
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = child_block.wip_capture_scope;
if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src);
emit_bb = true;
@@ -12783,7 +12805,6 @@ fn analyzeSwitchRuntimeBlock(
};
case_block.instructions.shrinkRetainingCapacity(0);
- case_block.wip_capture_scope = try mod.createCaptureScope(child_block.wip_capture_scope);
if (mod.backendSupportsFeature(.is_named_enum_value) and
special.body.len != 0 and block.wantSafety() and
@@ -17264,49 +17285,16 @@ fn zirThis(
return sema.analyzeDeclVal(block, src, this_decl_index);
}
-fn zirClosureCapture(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
+fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
const mod = sema.mod;
- const gpa = sema.gpa;
- const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
- // Closures are not necessarily constant values. For example, the
- // code might do something like this:
- // fn foo(x: anytype) void { const S = struct {field: @TypeOf(x)}; }
- // ...in which case the closure_capture instruction has access to a runtime
- // value only. In such case only the type is saved into the scope.
- const operand = try sema.resolveInst(inst_data.operand);
- const ty = sema.typeOf(operand);
- const key: CaptureScope.Key = .{
- .zir_index = inst,
- .index = block.wip_capture_scope,
- };
- if (try sema.resolveValue(operand)) |val| {
- try mod.comptime_capture_scopes.put(gpa, key, try val.intern(ty, mod));
- } else {
- try mod.runtime_capture_scopes.put(gpa, key, ty.toIntern());
- }
-}
+ const captures = mod.namespacePtr(block.namespace).captures;
-fn zirClosureGet(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const mod = sema.mod;
- //const ip = &mod.intern_pool;
- const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].inst_node;
- var scope: CaptureScope.Index = mod.declPtr(block.src_decl).src_scope;
- assert(scope != .none);
- // Note: The target closure must be in this scope list.
- // If it's not here, the zir is invalid, or the list is broken.
- const capture_ty = while (true) {
- // Note: We don't need to add a dependency here, because
- // decls always depend on their lexical parents.
- const key: CaptureScope.Key = .{
- .zir_index = inst_data.inst,
- .index = scope,
- };
- if (mod.comptime_capture_scopes.get(key)) |val|
- return Air.internedToRef(val);
- if (mod.runtime_capture_scopes.get(key)) |ty|
- break ty;
- scope = scope.parent(mod);
- assert(scope != .none);
+ const src_node: i32 = @bitCast(extended.operand);
+ const src = LazySrcLoc.nodeOffset(src_node);
+
+ const capture_ty = switch (captures[extended.small].unwrap()) {
+ .@"comptime" => |index| return Air.internedToRef(index),
+ .runtime => |index| index,
};
// The comptime case is handled already above. Runtime case below.
@@ -17322,15 +17310,15 @@ fn zirClosureGet(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
});
break :name null;
};
- const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node);
+ const node = sema.owner_decl.relativeToNodeIndex(src_node);
const token = tree.nodes.items(.main_token)[node];
break :name tree.tokenSlice(token);
};
const msg = if (name) |some|
- try sema.errMsg(block, inst_data.src(), "'{s}' not accessible outside function scope", .{some})
+ try sema.errMsg(block, src, "'{s}' not accessible outside function scope", .{some})
else
- try sema.errMsg(block, inst_data.src(), "variable not accessible outside function scope", .{});
+ try sema.errMsg(block, src, "variable not accessible outside function scope", .{});
errdefer msg.destroy(sema.gpa);
// TODO add "declared here" note
@@ -17350,15 +17338,15 @@ fn zirClosureGet(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
});
break :name null;
};
- const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node);
+ const node = sema.owner_decl.relativeToNodeIndex(src_node);
const token = tree.nodes.items(.main_token)[node];
break :name tree.tokenSlice(token);
};
const msg = if (name) |some|
- try sema.errMsg(block, inst_data.src(), "'{s}' not accessible from inner function", .{some})
+ try sema.errMsg(block, src, "'{s}' not accessible from inner function", .{some})
else
- try sema.errMsg(block, inst_data.src(), "variable not accessible from inner function", .{});
+ try sema.errMsg(block, src, "variable not accessible from inner function", .{});
errdefer msg.destroy(sema.gpa);
try sema.errNote(block, LazySrcLoc.nodeOffset(0), msg, "crossed function definition here", .{});
@@ -18631,7 +18619,6 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
.sema = sema,
.src_decl = block.src_decl,
.namespace = block.namespace,
- .wip_capture_scope = block.wip_capture_scope,
.instructions = .{},
.inlining = block.inlining,
.is_comptime = false,
@@ -18710,7 +18697,6 @@ fn zirTypeofPeer(
.sema = sema,
.src_decl = block.src_decl,
.namespace = block.namespace,
- .wip_capture_scope = block.wip_capture_scope,
.instructions = .{},
.inlining = block.inlining,
.is_comptime = false,
@@ -19186,7 +19172,6 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
.sema = sema,
.src_decl = block.src_decl,
.namespace = block.namespace,
- .wip_capture_scope = block.wip_capture_scope,
.instructions = .{},
.label = &labeled_block.label,
.inlining = block.inlining,
@@ -21462,6 +21447,7 @@ fn zirReify(
.parent = block.namespace.toOptional(),
.decl_index = new_decl_index,
.file_scope = block.getFileScope(mod),
+ .captures = &.{},
});
errdefer mod.destroyNamespace(new_namespace_index);
@@ -21670,6 +21656,7 @@ fn zirReify(
.parent = block.namespace.toOptional(),
.decl_index = new_decl_index,
.file_scope = block.getFileScope(mod),
+ .captures = &.{},
});
errdefer mod.destroyNamespace(new_namespace_index);
@@ -25919,7 +25906,7 @@ fn zirBuiltinExtern(
// TODO check duplicate extern
- const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node, .none);
+ const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node);
errdefer mod.destroyDecl(new_decl_index);
const new_decl = mod.declPtr(new_decl_index);
new_decl.name = options.name;
@@ -26515,7 +26502,6 @@ fn addSafetyCheck(
.sema = sema,
.src_decl = parent_block.src_decl,
.namespace = parent_block.namespace,
- .wip_capture_scope = parent_block.wip_capture_scope,
.instructions = .{},
.inlining = parent_block.inlining,
.is_comptime = false,
@@ -26624,7 +26610,6 @@ fn panicUnwrapError(
.sema = sema,
.src_decl = parent_block.src_decl,
.namespace = parent_block.namespace,
- .wip_capture_scope = parent_block.wip_capture_scope,
.instructions = .{},
.inlining = parent_block.inlining,
.is_comptime = false,
@@ -26741,7 +26726,6 @@ fn safetyCheckFormatted(
.sema = sema,
.src_decl = parent_block.src_decl,
.namespace = parent_block.namespace,
- .wip_capture_scope = parent_block.wip_capture_scope,
.instructions = .{},
.inlining = parent_block.inlining,
.is_comptime = false,
@@ -35766,7 +35750,6 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
.sema = &sema,
.src_decl = decl_index,
.namespace = struct_type.namespace.unwrap() orelse decl.src_namespace,
- .wip_capture_scope = try mod.createCaptureScope(decl.src_scope),
.instructions = .{},
.inlining = null,
.is_comptime = true,
@@ -35789,9 +35772,16 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
if (small.has_backing_int) {
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
+ const captures_len = if (small.has_captures_len) blk: {
+ const captures_len = zir.extra[extra_index];
+ extra_index += 1;
+ break :blk captures_len;
+ } else 0;
extra_index += @intFromBool(small.has_fields_len);
extra_index += @intFromBool(small.has_decls_len);
+ extra_index += captures_len;
+
const backing_int_body_len = zir.extra[extra_index];
extra_index += 1;
@@ -36500,6 +36490,12 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct {
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).Struct.fields.len;
+ const captures_len = if (small.has_captures_len) blk: {
+ const captures_len = zir.extra[extra_index];
+ extra_index += 1;
+ break :blk captures_len;
+ } else 0;
+
const fields_len = if (small.has_fields_len) blk: {
const fields_len = zir.extra[extra_index];
extra_index += 1;
@@ -36512,6 +36508,8 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct {
break :decls_len decls_len;
} else 0;
+ extra_index += captures_len;
+
// The backing integer cannot be handled until `resolveStructLayout()`.
if (small.has_backing_int) {
const backing_int_body_len = zir.extra[extra_index];
@@ -36584,7 +36582,6 @@ fn semaStructFields(
.sema = &sema,
.src_decl = decl_index,
.namespace = namespace_index,
- .wip_capture_scope = try mod.createCaptureScope(decl.src_scope),
.instructions = .{},
.inlining = null,
.is_comptime = true,
@@ -36842,7 +36839,6 @@ fn semaStructFieldInits(
.sema = &sema,
.src_decl = decl_index,
.namespace = namespace_index,
- .wip_capture_scope = try mod.createCaptureScope(decl.src_scope),
.instructions = .{},
.inlining = null,
.is_comptime = true,
@@ -36974,6 +36970,12 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
break :blk ty_ref;
} else .none;
+ const captures_len = if (small.has_captures_len) blk: {
+ const captures_len = zir.extra[extra_index];
+ extra_index += 1;
+ break :blk captures_len;
+ } else 0;
+
const body_len = if (small.has_body_len) blk: {
const body_len = zir.extra[extra_index];
extra_index += 1;
@@ -36992,8 +36994,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
break :decls_len decls_len;
} else 0;
- // Skip over decls.
- extra_index += decls_len;
+ // Skip over captures and decls.
+ extra_index += captures_len + decls_len;
const body = zir.bodySlice(extra_index, body_len);
extra_index += body.len;
@@ -37028,7 +37030,6 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
.sema = &sema,
.src_decl = decl_index,
.namespace = union_type.namespace,
- .wip_capture_scope = try mod.createCaptureScope(decl.src_scope),
.instructions = .{},
.inlining = null,
.is_comptime = true,
@@ -37372,7 +37373,7 @@ fn generateUnionTagTypeNumbered(
const ip = &mod.intern_pool;
const src_decl = mod.declPtr(block.src_decl);
- const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
+ const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node);
errdefer mod.destroyDecl(new_decl_index);
const fqn = try decl.fullyQualifiedName(mod);
const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});
@@ -37425,7 +37426,7 @@ fn generateUnionTagTypeSimple(
};
const fqn = try mod.declPtr(decl_index).fullyQualifiedName(mod);
const src_decl = mod.declPtr(block.src_decl);
- const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
+ const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node);
errdefer mod.destroyDecl(new_decl_index);
const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{
@@ -37460,7 +37461,6 @@ fn generateUnionTagTypeSimple(
}
fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
- const mod = sema.mod;
const gpa = sema.gpa;
const src = LazySrcLoc.nodeOffset(0);
@@ -37469,7 +37469,6 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
.sema = sema,
.src_decl = sema.owner_decl_index,
.namespace = sema.owner_decl.src_namespace,
- .wip_capture_scope = try mod.createCaptureScope(sema.owner_decl.src_scope),
.instructions = .{},
.inlining = null,
.is_comptime = true,
@@ -37510,7 +37509,6 @@ fn getBuiltinDecl(sema: *Sema, block: *Block, name: []const u8) CompileError!Int
}
fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
- const mod = sema.mod;
const ty_inst = try sema.getBuiltin(name);
var block: Block = .{
@@ -37518,7 +37516,6 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
.sema = sema,
.src_decl = sema.owner_decl_index,
.namespace = sema.owner_decl.src_namespace,
- .wip_capture_scope = try mod.createCaptureScope(sema.owner_decl.src_scope),
.instructions = .{},
.inlining = null,
.is_comptime = true,