Commit 426e737292
Changed files (1)
src
src/Autodoc.zig
@@ -328,7 +328,14 @@ pub fn generateZirData(self: *Autodoc) !void {
});
try self.files.put(self.arena, file, main_type_index);
- _ = try self.walkInstruction(file, &root_scope, .{}, Zir.main_struct_inst, false);
+ _ = try self.walkInstruction(
+ file,
+ &root_scope,
+ .{},
+ Zir.main_struct_inst,
+ false,
+ null,
+ );
if (self.ref_paths_pending_on_decls.count() > 0) {
@panic("some decl paths were never fully analized (pending on decls)");
@@ -979,6 +986,15 @@ const AutodocErrors = error{
UnexpectedEndOfFile,
} || std.fs.File.OpenError || std.fs.File.ReadError;
+/// `call` instructions will have loopy references to themselves
+/// whenever an as_node is required for a complex expression.
+/// This type is used to keep track of dangerous instruction
+/// numbers that we definitely don't want to recurse into.
+const CallContext = struct {
+ inst: usize,
+ prev: ?*const CallContext,
+};
+
/// Called when we need to analyze a Zir instruction.
/// For example it gets called by `generateZirData` on instruction 0,
/// which represents the top-level struct corresponding to the root file.
@@ -994,6 +1010,7 @@ fn walkInstruction(
parent_src: SrcLocInfo,
inst_index: usize,
need_type: bool, // true if the caller needs us to provide also a typeRef
+ call_ctx: ?*const CallContext,
) AutodocErrors!DocData.WalkResult {
const tags = file.zir.instructions.items(.tag);
const data = file.zir.instructions.items(.data);
@@ -1082,6 +1099,7 @@ fn walkInstruction(
.{},
Zir.main_struct_inst,
false,
+ call_ctx,
);
}
@@ -1113,6 +1131,7 @@ fn walkInstruction(
.{},
Zir.main_struct_inst,
need_type,
+ call_ctx,
);
},
.ret_type => {
@@ -1123,7 +1142,14 @@ fn walkInstruction(
},
.ret_node => {
const un_node = data[inst_index].un_node;
- return self.walkRef(file, parent_scope, parent_src, un_node.operand, false);
+ return self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ un_node.operand,
+ false,
+ call_ctx,
+ );
},
.ret_load => {
const un_node = data[inst_index].un_node;
@@ -1154,7 +1180,14 @@ fn walkInstruction(
}
if (result_ref) |rr| {
- return self.walkRef(file, parent_scope, parent_src, rr, need_type);
+ return self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ rr,
+ need_type,
+ call_ctx,
+ );
}
return DocData.WalkResult{
@@ -1163,11 +1196,25 @@ fn walkInstruction(
},
.closure_get => {
const inst_node = data[inst_index].inst_node;
- return try self.walkInstruction(file, parent_scope, parent_src, inst_node.inst, need_type);
+ return try self.walkInstruction(
+ file,
+ parent_scope,
+ parent_src,
+ inst_node.inst,
+ need_type,
+ call_ctx,
+ );
},
.closure_capture => {
const un_tok = data[inst_index].un_tok;
- return try self.walkRef(file, parent_scope, parent_src, un_tok.operand, need_type);
+ return try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ un_tok.operand,
+ need_type,
+ call_ctx,
+ );
},
.str => {
const str = data[inst_index].str.get(file.zir);
@@ -1214,6 +1261,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
false,
+ call_ctx,
);
const operand_index = self.exprs.items.len;
@@ -1284,6 +1332,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var start: DocData.WalkResult = try self.walkRef(
file,
@@ -1291,6 +1340,7 @@ fn walkInstruction(
parent_src,
extra.data.start,
false,
+ call_ctx,
);
const lhs_index = self.exprs.items.len;
@@ -1317,6 +1367,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var start: DocData.WalkResult = try self.walkRef(
file,
@@ -1324,6 +1375,7 @@ fn walkInstruction(
parent_src,
extra.data.start,
false,
+ call_ctx,
);
var end: DocData.WalkResult = try self.walkRef(
file,
@@ -1331,6 +1383,7 @@ fn walkInstruction(
parent_src,
extra.data.end,
false,
+ call_ctx,
);
const lhs_index = self.exprs.items.len;
@@ -1359,6 +1412,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var start: DocData.WalkResult = try self.walkRef(
file,
@@ -1366,6 +1420,7 @@ fn walkInstruction(
parent_src,
extra.data.start,
false,
+ call_ctx,
);
var end: DocData.WalkResult = try self.walkRef(
file,
@@ -1373,6 +1428,7 @@ fn walkInstruction(
parent_src,
extra.data.end,
false,
+ call_ctx,
);
var sentinel: DocData.WalkResult = try self.walkRef(
file,
@@ -1380,6 +1436,7 @@ fn walkInstruction(
parent_src,
extra.data.sentinel,
false,
+ call_ctx,
);
const lhs_index = self.exprs.items.len;
@@ -1410,6 +1467,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var start: DocData.WalkResult = try self.walkRef(
file,
@@ -1417,6 +1475,7 @@ fn walkInstruction(
parent_src,
extra.data.start,
false,
+ call_ctx,
);
var len: DocData.WalkResult = try self.walkRef(
file,
@@ -1424,6 +1483,7 @@ fn walkInstruction(
parent_src,
extra.data.len,
false,
+ call_ctx,
);
var sentinel_opt: ?DocData.WalkResult = if (extra.data.sentinel != .none)
try self.walkRef(
@@ -1432,6 +1492,7 @@ fn walkInstruction(
parent_src,
extra.data.sentinel,
false,
+ call_ctx,
)
else
null;
@@ -1492,6 +1553,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var rhs: DocData.WalkResult = try self.walkRef(
file,
@@ -1499,6 +1561,7 @@ fn walkInstruction(
parent_src,
extra.data.rhs,
false,
+ call_ctx,
);
const lhs_index = self.exprs.items.len;
@@ -1536,6 +1599,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var rhs: DocData.WalkResult = try self.walkRef(
file,
@@ -1543,6 +1607,7 @@ fn walkInstruction(
parent_src,
extra.data.rhs,
false,
+ call_ctx,
);
const lhs_index = self.exprs.items.len;
@@ -1599,7 +1664,14 @@ fn walkInstruction(
const un_node = data[inst_index].un_node;
const bin_index = self.exprs.items.len;
try self.exprs.append(self.arena, .{ .builtin = .{ .param = 0 } });
- const param = try self.walkRef(file, parent_scope, parent_src, un_node.operand, false);
+ const param = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ un_node.operand,
+ false,
+ call_ctx,
+ );
const param_index = self.exprs.items.len;
try self.exprs.append(self.arena, param.expr);
@@ -1623,6 +1695,7 @@ fn walkInstruction(
parent_src,
bool_br.lhs,
false,
+ call_ctx,
);
const lhs_index = self.exprs.items.len;
try self.exprs.append(self.arena, lhs.expr);
@@ -1634,6 +1707,7 @@ fn walkInstruction(
parent_src,
file.zir.extra[extra.end..][extra.data.body_len - 1],
false,
+ call_ctx,
);
const rhs_index = self.exprs.items.len;
try self.exprs.append(self.arena, rhs.expr);
@@ -1656,6 +1730,7 @@ fn walkInstruction(
parent_src,
extra.data.rhs,
false,
+ call_ctx,
);
const bin_index = self.exprs.items.len;
@@ -1670,6 +1745,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
self.exprs.items[bin_index] = .{ .builtin = .{ .name = @tagName(tags[inst_index]), .param = rhs_index } };
@@ -1718,6 +1794,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var rhs: DocData.WalkResult = try self.walkRef(
file,
@@ -1725,6 +1802,7 @@ fn walkInstruction(
parent_src,
extra.data.rhs,
false,
+ call_ctx,
);
const lhs_index = self.exprs.items.len;
@@ -1748,6 +1826,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var rhs: DocData.WalkResult = try self.walkRef(
file,
@@ -1755,6 +1834,7 @@ fn walkInstruction(
parent_src,
extra.data.rhs,
false,
+ call_ctx,
);
const type_slot_index = self.types.items.len;
@@ -1778,6 +1858,7 @@ fn walkInstruction(
parent_src,
extra.data.lhs,
false,
+ call_ctx,
);
var rhs: DocData.WalkResult = try self.walkRef(
file,
@@ -1785,6 +1866,7 @@ fn walkInstruction(
parent_src,
extra.data.rhs,
false,
+ call_ctx,
);
const type_slot_index = self.types.items.len;
try self.types.append(self.arena, .{ .ErrorUnion = .{
@@ -1820,6 +1902,7 @@ fn walkInstruction(
parent_src,
extra.data.elem_type,
false,
+ call_ctx,
);
// @check if `addrspace`, `bit_start` and `host_size` really need to be
@@ -1827,7 +1910,14 @@ fn walkInstruction(
var sentinel: ?DocData.Expr = null;
if (ptr.flags.has_sentinel) {
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
- const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
+ const ref_result = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ ref,
+ false,
+ call_ctx,
+ );
sentinel = ref_result.expr;
extra_index += 1;
}
@@ -1835,21 +1925,42 @@ fn walkInstruction(
var @"align": ?DocData.Expr = null;
if (ptr.flags.has_align) {
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
- const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
+ const ref_result = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ ref,
+ false,
+ call_ctx,
+ );
@"align" = ref_result.expr;
extra_index += 1;
}
var address_space: ?DocData.Expr = null;
if (ptr.flags.has_addrspace) {
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
- const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
+ const ref_result = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ ref,
+ false,
+ call_ctx,
+ );
address_space = ref_result.expr;
extra_index += 1;
}
var bit_start: ?DocData.Expr = null;
if (ptr.flags.has_bit_range) {
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
- const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
+ const ref_result = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ ref,
+ false,
+ call_ctx,
+ );
address_space = ref_result.expr;
extra_index += 1;
}
@@ -1857,7 +1968,14 @@ fn walkInstruction(
var host_size: ?DocData.Expr = null;
if (ptr.flags.has_bit_range) {
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
- const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
+ const ref_result = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ ref,
+ false,
+ call_ctx,
+ );
host_size = ref_result.expr;
}
@@ -1888,8 +2006,22 @@ fn walkInstruction(
const pl_node = data[inst_index].pl_node;
const bin = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
- const len = try self.walkRef(file, parent_scope, parent_src, bin.lhs, false);
- const child = try self.walkRef(file, parent_scope, parent_src, bin.rhs, false);
+ const len = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ bin.lhs,
+ false,
+ call_ctx,
+ );
+ const child = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ bin.rhs,
+ false,
+ call_ctx,
+ );
const type_slot_index = self.types.items.len;
try self.types.append(self.arena, .{
@@ -1907,9 +2039,30 @@ fn walkInstruction(
.array_type_sentinel => {
const pl_node = data[inst_index].pl_node;
const extra = file.zir.extraData(Zir.Inst.ArrayTypeSentinel, pl_node.payload_index);
- const len = try self.walkRef(file, parent_scope, parent_src, extra.data.len, false);
- const sentinel = try self.walkRef(file, parent_scope, parent_src, extra.data.sentinel, false);
- const elem_type = try self.walkRef(file, parent_scope, parent_src, extra.data.elem_type, false);
+ const len = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.data.len,
+ false,
+ call_ctx,
+ );
+ const sentinel = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.data.sentinel,
+ false,
+ call_ctx,
+ );
+ const elem_type = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.data.elem_type,
+ false,
+ call_ctx,
+ );
const type_slot_index = self.types.items.len;
try self.types.append(self.arena, .{
@@ -1931,10 +2084,24 @@ fn walkInstruction(
const array_data = try self.arena.alloc(usize, operands.len - 1);
std.debug.assert(operands.len > 0);
- var array_type = try self.walkRef(file, parent_scope, parent_src, operands[0], false);
+ var array_type = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ operands[0],
+ false,
+ call_ctx,
+ );
for (operands[1..], 0..) |op, idx| {
- const wr = try self.walkRef(file, parent_scope, parent_src, op, false);
+ const wr = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ op,
+ false,
+ call_ctx,
+ );
const expr_index = self.exprs.items.len;
try self.exprs.append(self.arena, wr.expr);
array_data[idx] = expr_index;
@@ -1952,7 +2119,14 @@ fn walkInstruction(
const array_data = try self.arena.alloc(usize, operands.len);
for (operands, 0..) |op, idx| {
- const wr = try self.walkRef(file, parent_scope, parent_src, op, false);
+ const wr = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ op,
+ false,
+ call_ctx,
+ );
const expr_index = self.exprs.items.len;
try self.exprs.append(self.arena, wr.expr);
array_data[idx] = expr_index;
@@ -1970,10 +2144,24 @@ fn walkInstruction(
const array_data = try self.arena.alloc(usize, operands.len - 1);
std.debug.assert(operands.len > 0);
- var array_type = try self.walkRef(file, parent_scope, parent_src, operands[0], false);
+ var array_type = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ operands[0],
+ false,
+ call_ctx,
+ );
for (operands[1..], 0..) |op, idx| {
- const wr = try self.walkRef(file, parent_scope, parent_src, op, false);
+ const wr = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ op,
+ false,
+ call_ctx,
+ );
const expr_index = self.exprs.items.len;
try self.exprs.append(self.arena, wr.expr);
array_data[idx] = expr_index;
@@ -2002,7 +2190,14 @@ fn walkInstruction(
const array_data = try self.arena.alloc(usize, operands.len);
for (operands, 0..) |op, idx| {
- const wr = try self.walkRef(file, parent_scope, parent_src, op, false);
+ const wr = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ op,
+ false,
+ call_ctx,
+ );
const expr_index = self.exprs.items.len;
try self.exprs.append(self.arena, wr.expr);
array_data[idx] = expr_index;
@@ -2041,6 +2236,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
need_type,
+ call_ctx,
);
switch (operand.expr) {
.int => |*int| int.negated = true,
@@ -2065,6 +2261,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
false,
+ call_ctx,
);
const operand_index = self.exprs.items.len;
try self.exprs.append(self.arena, operand.expr);
@@ -2083,6 +2280,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
need_type,
+ call_ctx,
);
const operand_index = self.exprs.items.len;
try self.exprs.append(self.arena, operand.expr);
@@ -2101,6 +2299,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
false,
+ call_ctx,
);
const operand_index = self.exprs.items.len;
try self.exprs.append(self.arena, operand.expr);
@@ -2115,7 +2314,14 @@ fn walkInstruction(
const pl_node = data[inst_index].pl_node;
const extra = file.zir.extraData(Zir.Inst.SwitchBlock, pl_node.payload_index);
- const switch_cond = try self.walkRef(file, parent_scope, parent_src, extra.data.operand, false);
+ const switch_cond = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.data.operand,
+ false,
+ call_ctx,
+ );
const cond_index = self.exprs.items.len;
try self.exprs.append(self.arena, switch_cond.expr);
_ = cond_index;
@@ -2162,6 +2368,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
need_type,
+ call_ctx,
);
const operand_index = self.exprs.items.len;
try self.exprs.append(self.arena, operand.expr);
@@ -2181,6 +2388,7 @@ fn walkInstruction(
parent_src,
data[body].@"break".operand,
false,
+ call_ctx,
);
const operand_index = self.exprs.items.len;
@@ -2201,6 +2409,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
need_type,
+ call_ctx,
);
const operand_index = self.exprs.items.len;
@@ -2214,12 +2423,31 @@ fn walkInstruction(
.as_node, .as_shift_operand => {
const pl_node = data[inst_index].pl_node;
const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);
+
+ // Skip the as_node if the destination type is a call instruction
+ if (Zir.refToIndex(extra.data.dest_type)) |dti| {
+ var maybe_cc = call_ctx;
+ while (maybe_cc) |cc| : (maybe_cc = cc.prev) {
+ if (cc.inst == dti) {
+ return try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.data.operand,
+ false,
+ call_ctx,
+ );
+ }
+ }
+ }
+
const dest_type_walk = try self.walkRef(
file,
parent_scope,
parent_src,
extra.data.dest_type,
false,
+ call_ctx,
);
const operand = try self.walkRef(
@@ -2228,6 +2456,7 @@ fn walkInstruction(
parent_src,
extra.data.operand,
false,
+ call_ctx,
);
const operand_idx = self.exprs.items.len;
@@ -2257,6 +2486,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
false,
+ call_ctx,
);
const operand_idx = self.types.items.len;
@@ -2332,7 +2562,14 @@ fn walkInstruction(
}
}
- break :blk try self.walkRef(file, parent_scope, parent_src, lhs_ref, false);
+ break :blk try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ lhs_ref,
+ false,
+ call_ctx,
+ );
};
try path.append(self.arena, wr.expr);
@@ -2400,6 +2637,7 @@ fn walkInstruction(
return res;
},
need_type,
+ call_ctx,
);
},
.break_inline => {
@@ -2410,6 +2648,7 @@ fn walkInstruction(
parent_src,
@"break".operand,
need_type,
+ call_ctx,
);
},
.struct_init => {
@@ -2448,6 +2687,7 @@ fn walkInstruction(
field_src,
field_extra.data.container_type,
false,
+ call_ctx,
);
type_ref = wr.expr;
}
@@ -2459,6 +2699,7 @@ fn walkInstruction(
parent_src,
init_extra.data.init,
need_type,
+ call_ctx,
);
fv.* = .{ .name = field_name, .val = value };
}
@@ -2477,6 +2718,7 @@ fn walkInstruction(
parent_src,
un_node.operand,
false,
+ call_ctx,
);
return DocData.WalkResult{
@@ -2503,6 +2745,7 @@ fn walkInstruction(
parent_src,
init_extra.data.init,
need_type,
+ call_ctx,
);
fv.* = .{ .name = field_name, .val = value };
idx = init_extra.end;
@@ -2576,7 +2819,14 @@ fn walkInstruction(
const pl_node = data[inst_index].pl_node;
const extra = file.zir.extraData(Zir.Inst.Call, pl_node.payload_index);
- const callee = try self.walkRef(file, parent_scope, parent_src, extra.data.callee, need_type);
+ const callee = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.data.callee,
+ need_type,
+ call_ctx,
+ );
const args_len = extra.data.flags.args_len;
var args = try self.arena.alloc(DocData.Expr, args_len);
@@ -2591,7 +2841,17 @@ fn walkInstruction(
// to show discrepancies between the types of provided
// arguments and the types declared in the function
// signature for its parameters.
- const wr = try self.walkRef(file, parent_scope, parent_src, ref, false);
+ const wr = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ ref,
+ false,
+ &.{
+ .inst = inst_index,
+ .prev = call_ctx,
+ },
+ );
args[i] = wr.expr;
}
@@ -2639,6 +2899,7 @@ fn walkInstruction(
self_ast_node_index,
type_slot_index,
tags[inst_index] == .func_inferred,
+ call_ctx,
);
return result;
@@ -2654,6 +2915,7 @@ fn walkInstruction(
inst_index,
self_ast_node_index,
type_slot_index,
+ call_ctx,
);
return result;
@@ -2678,7 +2940,14 @@ fn walkInstruction(
var array_type: ?DocData.Expr = null;
for (args, 0..) |arg, idx| {
- const wr = try self.walkRef(file, parent_scope, parent_src, arg, idx == 0);
+ const wr = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ arg,
+ idx == 0,
+ call_ctx,
+ );
if (idx == 0) {
array_type = wr.typeRef;
}
@@ -2740,6 +3009,7 @@ fn walkInstruction(
src_info,
&decl_indexes,
&priv_decl_indexes,
+ call_ctx,
);
self.types.items[type_slot_index] = .{
@@ -2778,7 +3048,14 @@ fn walkInstruction(
if (small.has_lib_name) extra_index += 1;
if (small.has_align) extra_index += 1;
- const var_type = try self.walkRef(file, parent_scope, parent_src, extra.data.var_type, need_type);
+ const var_type = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.data.var_type,
+ need_type,
+ call_ctx,
+ );
var value: DocData.WalkResult = .{
.typeRef = var_type.expr,
@@ -2787,7 +3064,14 @@ fn walkInstruction(
if (small.has_init) {
const var_init_ref = @as(Ref, @enumFromInt(file.zir.extra[extra_index]));
- const var_init = try self.walkRef(file, parent_scope, parent_src, var_init_ref, need_type);
+ const var_init = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ var_init_ref,
+ need_type,
+ call_ctx,
+ );
value.expr = var_init.expr;
value.typeRef = var_init.typeRef;
}
@@ -2853,6 +3137,7 @@ fn walkInstruction(
src_info,
&decl_indexes,
&priv_decl_indexes,
+ call_ctx,
);
// Analyze the tag once all decls have been analyzed
@@ -2862,6 +3147,7 @@ fn walkInstruction(
parent_src,
tt_ref,
false,
+ call_ctx,
)).expr else null;
// Fields
@@ -2883,6 +3169,7 @@ fn walkInstruction(
&field_type_refs,
&field_name_indexes,
extra_index,
+ call_ctx,
);
self.ast_nodes.items[self_ast_node_index].fields = field_name_indexes.items;
@@ -2948,7 +3235,14 @@ fn walkInstruction(
const tag_type = file.zir.extra[extra_index];
extra_index += 1;
const tag_ref = @as(Ref, @enumFromInt(tag_type));
- const wr = try self.walkRef(file, parent_scope, parent_src, tag_ref, false);
+ const wr = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ tag_ref,
+ false,
+ call_ctx,
+ );
break :blk wr.expr;
} else null;
@@ -2974,6 +3268,7 @@ fn walkInstruction(
src_info,
&decl_indexes,
&priv_decl_indexes,
+ call_ctx,
);
// const body = file.zir.extra[extra_index..][0..body_len];
@@ -3005,7 +3300,14 @@ fn walkInstruction(
const value_expr: ?DocData.Expr = if (has_value) blk: {
const value_ref = file.zir.extra[extra_index];
extra_index += 1;
- const value = try self.walkRef(file, &scope, src_info, @as(Ref, @enumFromInt(value_ref)), false);
+ const value = try self.walkRef(
+ file,
+ &scope,
+ src_info,
+ @as(Ref, @enumFromInt(value_ref)),
+ false,
+ call_ctx,
+ );
break :blk value.expr;
} else null;
try field_values.append(self.arena, value_expr);
@@ -3095,14 +3397,28 @@ fn walkInstruction(
extra_index += 1; // backing_int_body_len
if (backing_int_body_len == 0) {
const backing_int_ref = @as(Ref, @enumFromInt(file.zir.extra[extra_index]));
- const backing_int_res = try self.walkRef(file, &scope, src_info, backing_int_ref, true);
+ const backing_int_res = try self.walkRef(
+ file,
+ &scope,
+ src_info,
+ backing_int_ref,
+ true,
+ call_ctx,
+ );
backing_int = backing_int_res.expr;
extra_index += 1; // backing_int_ref
} else {
const backing_int_body = file.zir.extra[extra_index..][0..backing_int_body_len];
const break_inst = backing_int_body[backing_int_body.len - 1];
const operand = data[break_inst].@"break".operand;
- const backing_int_res = try self.walkRef(file, &scope, src_info, operand, true);
+ const backing_int_res = try self.walkRef(
+ file,
+ &scope,
+ src_info,
+ operand,
+ true,
+ call_ctx,
+ );
backing_int = backing_int_res.expr;
extra_index += backing_int_body_len; // backing_int_body_inst
}
@@ -3123,6 +3439,7 @@ fn walkInstruction(
src_info,
&decl_indexes,
&priv_decl_indexes,
+ call_ctx,
);
var field_type_refs: std.ArrayListUnmanaged(DocData.Expr) = .{};
@@ -3138,6 +3455,7 @@ fn walkInstruction(
&field_name_indexes,
extra_index,
small.is_tuple,
+ call_ctx,
);
self.ast_nodes.items[self_ast_node_index].fields = field_name_indexes.items;
@@ -3194,7 +3512,14 @@ fn walkInstruction(
const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data;
const bin_index = self.exprs.items.len;
try self.exprs.append(self.arena, .{ .builtin = .{ .param = 0 } });
- const param = try self.walkRef(file, parent_scope, parent_src, extra.operand, false);
+ const param = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.operand,
+ false,
+ call_ctx,
+ );
const param_index = self.exprs.items.len;
try self.exprs.append(self.arena, param.expr);
@@ -3213,7 +3538,14 @@ fn walkInstruction(
const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data;
const bin_index = self.exprs.items.len;
try self.exprs.append(self.arena, .{ .builtin = .{ .param = 0 } });
- const param = try self.walkRef(file, parent_scope, parent_src, extra.operand, false);
+ const param = try self.walkRef(
+ file,
+ parent_scope,
+ parent_src,
+ extra.operand,
+ false,
+ call_ctx,
+ );
const param_index = self.exprs.items.len;
try self.exprs.append(self.arena, param.expr);
@@ -3241,6 +3573,7 @@ fn walkInstruction(
parent_src,
extra.ptr,
false,
+ call_ctx,
);
try self.exprs.append(self.arena, ptr.expr);
@@ -3251,6 +3584,7 @@ fn walkInstruction(
parent_src,
extra.expected_value,
false,
+ call_ctx,
);
try self.exprs.append(self.arena, expected_value.expr);
@@ -3261,6 +3595,7 @@ fn walkInstruction(
parent_src,
extra.new_value,
false,
+ call_ctx,
);
try self.exprs.append(self.arena, new_value.expr);
@@ -3271,6 +3606,7 @@ fn walkInstruction(
parent_src,
extra.success_order,
false,
+ call_ctx,
);
try self.exprs.append(self.arena, success_order.expr);
@@ -3281,6 +3617,7 @@ fn walkInstruction(
parent_src,
extra.failure_order,
false,
+ call_ctx,
);
try self.exprs.append(self.arena, failure_order.expr);
@@ -3319,6 +3656,7 @@ fn analyzeAllDecls(
parent_src: SrcLocInfo,
decl_indexes: *std.ArrayListUnmanaged(usize),
priv_decl_indexes: *std.ArrayListUnmanaged(usize),
+ call_ctx: ?*const CallContext,
) AutodocErrors!usize {
const first_decl_indexes_slot = decl_indexes.items.len;
const original_it = file.zir.declIterator(@as(u32, @intCast(parent_inst_index)));
@@ -3358,6 +3696,7 @@ fn analyzeAllDecls(
decl_indexes,
priv_decl_indexes,
d,
+ call_ctx,
);
},
}
@@ -3387,6 +3726,7 @@ fn analyzeAllDecls(
decl_indexes,
priv_decl_indexes,
d,
+ call_ctx,
);
}
@@ -3420,6 +3760,7 @@ fn analyzeDecl(
decl_indexes: *std.ArrayListUnmanaged(usize),
priv_decl_indexes: *std.ArrayListUnmanaged(usize),
d: Zir.DeclIterator.Item,
+ call_ctx: ?*const CallContext,
) AutodocErrors!void {
const data = file.zir.instructions.items(.data);
const is_pub = @as(u1, @truncate(d.flags >> 0)) != 0;
@@ -3497,7 +3838,14 @@ fn analyzeDecl(
break :idx idx;
};
- const walk_result = try self.walkInstruction(file, scope, decl_src, value_index, true);
+ const walk_result = try self.walkInstruction(
+ file,
+ scope,
+ decl_src,
+ value_index,
+ true,
+ call_ctx,
+ );
const kind: []const u8 = if (try self.declIsVar(file, value_pl_node.src_node, parent_src)) "var" else "const";
@@ -3545,6 +3893,7 @@ fn analyzeUsingnamespaceDecl(
decl_indexes: *std.ArrayListUnmanaged(usize),
priv_decl_indexes: *std.ArrayListUnmanaged(usize),
d: Zir.DeclIterator.Item,
+ call_ctx: ?*const CallContext,
) AutodocErrors!void {
const data = file.zir.instructions.items(.data);
@@ -3574,7 +3923,14 @@ fn analyzeUsingnamespaceDecl(
break :idx idx;
};
- const walk_result = try self.walkInstruction(file, scope, decl_src, value_index, true);
+ const walk_result = try self.walkInstruction(
+ file,
+ scope,
+ decl_src,
+ value_index,
+ true,
+ call_ctx,
+ );
const decl_slot_index = self.decls.items.len;
try self.decls.append(self.arena, .{
@@ -4192,6 +4548,7 @@ fn analyzeFancyFunction(
inst_index: usize,
self_ast_node_index: usize,
type_slot_index: usize,
+ call_ctx: ?*const CallContext,
) AutodocErrors!DocData.WalkResult {
const tags = file.zir.instructions.items(.tag);
const data = file.zir.instructions.items(.data);
@@ -4253,7 +4610,14 @@ fn analyzeFancyFunction(
const break_index = file.zir.extra[extra.end..][extra.data.body_len - 1];
const break_operand = data[break_index].@"break".operand;
- const param_type_ref = try self.walkRef(file, scope, parent_src, break_operand, false);
+ const param_type_ref = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ break_operand,
+ false,
+ call_ctx,
+ );
param_type_refs.appendAssumeCapacity(param_type_ref.expr);
},
@@ -4277,7 +4641,14 @@ fn analyzeFancyFunction(
if (extra.data.bits.has_align_ref) {
const align_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
align_index = self.exprs.items.len;
- _ = try self.walkRef(file, scope, parent_src, align_ref, false);
+ _ = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ align_ref,
+ false,
+ call_ctx,
+ );
extra_index += 1;
} else if (extra.data.bits.has_align_body) {
const align_body_len = file.zir.extra[extra_index];
@@ -4294,7 +4665,14 @@ fn analyzeFancyFunction(
if (extra.data.bits.has_addrspace_ref) {
const addrspace_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
addrspace_index = self.exprs.items.len;
- _ = try self.walkRef(file, scope, parent_src, addrspace_ref, false);
+ _ = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ addrspace_ref,
+ false,
+ call_ctx,
+ );
extra_index += 1;
} else if (extra.data.bits.has_addrspace_body) {
const addrspace_body_len = file.zir.extra[extra_index];
@@ -4311,7 +4689,14 @@ fn analyzeFancyFunction(
if (extra.data.bits.has_section_ref) {
const section_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
section_index = self.exprs.items.len;
- _ = try self.walkRef(file, scope, parent_src, section_ref, false);
+ _ = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ section_ref,
+ false,
+ call_ctx,
+ );
extra_index += 1;
} else if (extra.data.bits.has_section_body) {
const section_body_len = file.zir.extra[extra_index];
@@ -4327,7 +4712,14 @@ fn analyzeFancyFunction(
var cc_index: ?usize = null;
if (extra.data.bits.has_cc_ref and !extra.data.bits.has_cc_body) {
const cc_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
- const cc_expr = try self.walkRef(file, scope, parent_src, cc_ref, false);
+ const cc_expr = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ cc_ref,
+ false,
+ call_ctx,
+ );
cc_index = self.exprs.items.len;
try self.exprs.append(self.arena, cc_expr.expr);
@@ -4341,7 +4733,14 @@ fn analyzeFancyFunction(
// We assume the body ends with a break_inline
const break_index = cc_body[cc_body.len - 1];
const break_operand = data[break_index].@"break".operand;
- const cc_expr = try self.walkRef(file, scope, parent_src, break_operand, false);
+ const cc_expr = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ break_operand,
+ false,
+ call_ctx,
+ );
cc_index = self.exprs.items.len;
try self.exprs.append(self.arena, cc_expr.expr);
@@ -4357,14 +4756,28 @@ fn analyzeFancyFunction(
.none => DocData.Expr{ .void = .{} },
else => blk: {
const ref = fn_info.ret_ty_ref;
- const wr = try self.walkRef(file, scope, parent_src, ref, false);
+ const wr = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ ref,
+ false,
+ call_ctx,
+ );
break :blk wr.expr;
},
},
else => blk: {
const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
const break_operand = data[last_instr_index].@"break".operand;
- const wr = try self.walkRef(file, scope, parent_src, break_operand, false);
+ const wr = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ break_operand,
+ false,
+ call_ctx,
+ );
break :blk wr.expr;
},
};
@@ -4381,6 +4794,7 @@ fn analyzeFancyFunction(
scope,
parent_src,
fn_info.body[0],
+ call_ctx,
);
} else {
break :blk null;
@@ -4426,6 +4840,7 @@ fn analyzeFunction(
self_ast_node_index: usize,
type_slot_index: usize,
ret_is_inferred_error_set: bool,
+ call_ctx: ?*const CallContext,
) AutodocErrors!DocData.WalkResult {
const tags = file.zir.instructions.items(.tag);
const data = file.zir.instructions.items(.data);
@@ -4487,7 +4902,14 @@ fn analyzeFunction(
const break_index = file.zir.extra[extra.end..][extra.data.body_len - 1];
const break_operand = data[break_index].@"break".operand;
- const param_type_ref = try self.walkRef(file, scope, parent_src, break_operand, false);
+ const param_type_ref = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ break_operand,
+ false,
+ call_ctx,
+ );
param_type_refs.appendAssumeCapacity(param_type_ref.expr);
},
@@ -4500,14 +4922,28 @@ fn analyzeFunction(
.none => DocData.Expr{ .void = .{} },
else => blk: {
const ref = fn_info.ret_ty_ref;
- const wr = try self.walkRef(file, scope, parent_src, ref, false);
+ const wr = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ ref,
+ false,
+ call_ctx,
+ );
break :blk wr.expr;
},
},
else => blk: {
const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
const break_operand = data[last_instr_index].@"break".operand;
- const wr = try self.walkRef(file, scope, parent_src, break_operand, false);
+ const wr = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ break_operand,
+ false,
+ call_ctx,
+ );
break :blk wr.expr;
},
};
@@ -4524,6 +4960,7 @@ fn analyzeFunction(
scope,
parent_src,
fn_info.body[0],
+ call_ctx,
);
} else {
break :blk null;
@@ -4570,6 +5007,7 @@ fn getGenericReturnType(
scope: *Scope,
parent_src: SrcLocInfo, // function decl line
body_main_block: usize,
+ call_ctx: ?*const CallContext,
) !DocData.Expr {
const tags = file.zir.instructions.items(.tag);
const data = file.zir.instructions.items(.data);
@@ -4581,7 +5019,14 @@ fn getGenericReturnType(
const maybe_ret_node = file.zir.extra[extra.end..][extra.data.body_len - 4];
switch (tags[maybe_ret_node]) {
.ret_node, .ret_load => {
- const wr = try self.walkInstruction(file, scope, parent_src, maybe_ret_node, false);
+ const wr = try self.walkInstruction(
+ file,
+ scope,
+ parent_src,
+ maybe_ret_node,
+ false,
+ call_ctx,
+ );
return wr.expr;
},
else => {
@@ -4599,6 +5044,7 @@ fn collectUnionFieldInfo(
field_type_refs: *std.ArrayListUnmanaged(DocData.Expr),
field_name_indexes: *std.ArrayListUnmanaged(usize),
ei: usize,
+ call_ctx: ?*const CallContext,
) !void {
if (fields_len == 0) return;
var extra_index = ei;
@@ -4641,7 +5087,14 @@ fn collectUnionFieldInfo(
// type
{
- const walk_result = try self.walkRef(file, scope, parent_src, field_type, false);
+ const walk_result = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ field_type,
+ false,
+ call_ctx,
+ );
try field_type_refs.append(self.arena, walk_result.expr);
}
@@ -4671,6 +5124,7 @@ fn collectStructFieldInfo(
field_name_indexes: *std.ArrayListUnmanaged(usize),
ei: usize,
is_tuple: bool,
+ call_ctx: ?*const CallContext,
) !void {
if (fields_len == 0) return;
var extra_index = ei;
@@ -4744,7 +5198,14 @@ fn collectStructFieldInfo(
for (fields) |field| {
const type_expr = expr: {
if (field.type_ref != .none) {
- const walk_result = try self.walkRef(file, scope, parent_src, field.type_ref, false);
+ const walk_result = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ field.type_ref,
+ false,
+ call_ctx,
+ );
break :expr walk_result.expr;
}
@@ -4760,7 +5221,14 @@ fn collectStructFieldInfo(
.col = 0,
.fields = null, // walkInstruction will fill `fields` if necessary
});
- const walk_result = try self.walkRef(file, scope, parent_src, operand, false);
+ const walk_result = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ operand,
+ false,
+ call_ctx,
+ );
break :expr walk_result.expr;
};
@@ -4776,7 +5244,14 @@ fn collectStructFieldInfo(
const break_inst = body[body.len - 1];
const operand = data[break_inst].@"break".operand;
- const walk_result = try self.walkRef(file, scope, parent_src, operand, false);
+ const walk_result = try self.walkRef(
+ file,
+ scope,
+ parent_src,
+ operand,
+ false,
+ call_ctx,
+ );
break :def walk_result.expr;
};
@@ -4812,6 +5287,7 @@ fn walkRef(
parent_src: SrcLocInfo,
ref: Ref,
need_type: bool, // true when the caller needs also a typeRef for the return value
+ call_ctx: ?*const CallContext,
) AutodocErrors!DocData.WalkResult {
if (ref == .none) {
return .{ .expr = .{ .comptimeExpr = 0 } };
@@ -4824,7 +5300,14 @@ fn walkRef(
.expr = .{ .type = @intFromEnum(ref) },
};
} else if (Zir.refToIndex(ref)) |zir_index| {
- return self.walkInstruction(file, parent_scope, parent_src, zir_index, need_type);
+ return self.walkInstruction(
+ file,
+ parent_scope,
+ parent_src,
+ zir_index,
+ need_type,
+ call_ctx,
+ );
} else {
switch (ref) {
else => {