Commit fbe9fcd243

mlugg <mlugg@mlugg.co.uk>
2023-09-20 19:46:45
Autodoc: prevent infinite recursion when resolving parameter type
Note that this will also be necessary for `switch_block` and `switch_block_ref` once those instructions are correctly implemented.
1 parent 5fa260b
Changed files (1)
src/Autodoc.zig
@@ -45,6 +45,14 @@ ref_paths_pending_on_types: std.AutoHashMapUnmanaged(
     std.ArrayListUnmanaged(RefPathResumeInfo),
 ) = .{},
 
+/// A set of ZIR instruction refs which have a meaning other than the
+/// instruction they refer to. For instance, during analysis of the arguments to
+/// a `call`, the index of the `call` itself is repurposed to refer to the
+/// parameter type.
+/// TODO: there should be some kind of proper handling for these instructions;
+/// currently we just ignore them!
+repurposed_insts: std.AutoHashMapUnmanaged(Zir.Inst.Index, void) = .{},
+
 const RefPathResumeInfo = struct {
     file: *File,
     ref_path: []DocData.Expr,
@@ -954,6 +962,11 @@ fn walkInstruction(
     const tags = file.zir.instructions.items(.tag);
     const data = file.zir.instructions.items(.data);
 
+    if (self.repurposed_insts.contains(@intCast(inst_index))) {
+        // TODO: better handling here
+        return .{ .expr = .{ .comptimeExpr = 0 } };
+    }
+
     // We assume that the topmost ast_node entry corresponds to our decl
     const self_ast_node_index = self.ast_nodes.items.len - 1;
 
@@ -3022,6 +3035,9 @@ fn walkInstruction(
             var args = try self.arena.alloc(DocData.Expr, args_len);
             const body = file.zir.extra[extra.end..];
 
+            try self.repurposed_insts.put(self.arena, @intCast(inst_index), {});
+            defer _ = self.repurposed_insts.remove(@intCast(inst_index));
+
             var i: usize = 0;
             while (i < args_len) : (i += 1) {
                 const arg_end = file.zir.extra[extra.end + i];