Commit 54460e39ac

mlugg <mlugg@mlugg.co.uk>
2023-06-11 15:51:08
Autodoc: make it work under InternPool
1 parent 5b6906c
src/Autodoc.zig
@@ -8,6 +8,7 @@ const CompilationModule = @import("Module.zig");
 const File = CompilationModule.File;
 const Module = @import("Package.zig");
 const Tokenizer = std.zig.Tokenizer;
+const InternPool = @import("InternPool.zig");
 const Zir = @import("Zir.zig");
 const Ref = Zir.Inst.Ref;
 const log = std.log.scoped(.autodoc);
@@ -106,18 +107,20 @@ pub fn generateZirData(self: *Autodoc) !void {
     const file = self.comp_module.import_table.get(abs_root_src_path).?; // file is expected to be present in the import table
     // Append all the types in Zir.Inst.Ref.
     {
-        try self.types.append(self.arena, .{
-            .ComptimeExpr = .{ .name = "ComptimeExpr" },
-        });
-
-        // this skips Ref.none but it's ok becuse we replaced it with ComptimeExpr
-        var i: u32 = 1;
-        while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) {
+        comptime std.debug.assert(@enumToInt(InternPool.Index.first_type) == 0);
+        var i: u32 = 0;
+        while (i <= @enumToInt(InternPool.Index.last_type)) : (i += 1) {
+            const ip_index = @intToEnum(InternPool.Index, i);
             var tmpbuf = std.ArrayList(u8).init(self.arena);
-            try Ref.typed_value_map[i].val.fmtDebug().format("", .{}, tmpbuf.writer());
+            if (ip_index == .generic_poison_type) {
+                // Not a real type, doesn't have a normal name
+                try tmpbuf.writer().writeAll("(generic poison)");
+            } else {
+                try ip_index.toType().fmt(self.comp_module).format("", .{}, tmpbuf.writer());
+            }
             try self.types.append(
                 self.arena,
-                switch (@intToEnum(Ref, i)) {
+                switch (ip_index) {
                     else => blk: {
                         // TODO: map the remaining refs to a correct type
                         //       instead of just assinging "array" to them.
@@ -1038,7 +1041,7 @@ fn walkInstruction(
         .ret_load => {
             const un_node = data[inst_index].un_node;
             const res_ptr_ref = un_node.operand;
-            const res_ptr_inst = @enumToInt(res_ptr_ref) - Ref.typed_value_map.len;
+            const res_ptr_inst = Zir.refToIndex(res_ptr_ref).?;
             // TODO: this instruction doesn't let us know trivially if there's
             //       branching involved or not. For now here's the strat:
             //       We search backwarts until `ret_ptr` for `store_node`,
@@ -2155,11 +2158,10 @@ fn walkInstruction(
             const lhs_ref = blk: {
                 var lhs_extra = extra;
                 while (true) {
-                    if (@enumToInt(lhs_extra.data.lhs) < Ref.typed_value_map.len) {
+                    const lhs = Zir.refToIndex(lhs_extra.data.lhs) orelse {
                         break :blk lhs_extra.data.lhs;
-                    }
+                    };
 
-                    const lhs = @enumToInt(lhs_extra.data.lhs) - Ref.typed_value_map.len;
                     if (tags[lhs] != .field_val and
                         tags[lhs] != .field_ptr and
                         tags[lhs] != .field_type) break :blk lhs_extra.data.lhs;
@@ -2186,8 +2188,7 @@ fn walkInstruction(
             // TODO: double check that we really don't need type info here
 
             const wr = blk: {
-                if (@enumToInt(lhs_ref) >= Ref.typed_value_map.len) {
-                    const lhs_inst = @enumToInt(lhs_ref) - Ref.typed_value_map.len;
+                if (Zir.refToIndex(lhs_ref)) |lhs_inst| {
                     if (tags[lhs_inst] == .call or tags[lhs_inst] == .field_call) {
                         break :blk DocData.WalkResult{
                             .expr = .{
@@ -4670,16 +4671,19 @@ fn walkRef(
     ref: Ref,
     need_type: bool, // true when the caller needs also a typeRef for the return value
 ) AutodocErrors!DocData.WalkResult {
-    const enum_value = @enumToInt(ref);
-    if (enum_value <= @enumToInt(Ref.anyerror_void_error_union_type)) {
+    if (ref == .none) {
+        return .{ .expr = .{ .comptimeExpr = 0 } };
+    } else if (@enumToInt(ref) <= @enumToInt(InternPool.Index.last_type)) {
         // We can just return a type that indexes into `types` with the
         // enum value because in the beginning we pre-filled `types` with
         // the types that are listed in `Ref`.
         return DocData.WalkResult{
             .typeRef = .{ .type = @enumToInt(std.builtin.TypeId.Type) },
-            .expr = .{ .type = enum_value },
+            .expr = .{ .type = @enumToInt(ref) },
         };
-    } else if (enum_value < Ref.typed_value_map.len) {
+    } else if (Zir.refToIndex(ref)) |zir_index| {
+        return self.walkInstruction(file, parent_scope, parent_src, zir_index, need_type);
+    } else {
         switch (ref) {
             else => {
                 panicWithContext(
@@ -4772,9 +4776,6 @@ fn walkRef(
             //     } };
             // },
         }
-    } else {
-        const zir_index = enum_value - Ref.typed_value_map.len;
-        return self.walkInstruction(file, parent_scope, parent_src, zir_index, need_type);
     }
 }
 
src/Compilation.zig
@@ -2074,7 +2074,6 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
     if (!build_options.only_c and !build_options.only_core_functionality) {
         if (comp.emit_docs) |doc_location| {
             if (comp.bin_file.options.module) |module| {
-                if (true) @panic("TODO: get autodoc working again in this branch");
                 var autodoc = Autodoc.init(module, doc_location);
                 defer autodoc.deinit();
                 try autodoc.generateZirData();
src/type.zig
@@ -315,23 +315,25 @@ pub const Type = struct {
                 .comptime_float,
                 .noreturn,
                 => return writer.writeAll(@tagName(s)),
+
                 .null,
                 .undefined,
                 => try writer.print("@TypeOf({s})", .{@tagName(s)}),
+
                 .enum_literal => try writer.print("@TypeOf(.{s})", .{@tagName(s)}),
-                .atomic_order,
-                .atomic_rmw_op,
-                .calling_convention,
-                .address_space,
-                .float_mode,
-                .reduce_op,
-                .call_modifier,
-                .prefetch_options,
-                .export_options,
-                .extern_options,
-                .type_info,
-                .generic_poison,
-                => unreachable,
+                .atomic_order => try writer.writeAll("std.builtin.AtomicOrder"),
+                .atomic_rmw_op => try writer.writeAll("std.builtin.AtomicRmwOp"),
+                .calling_convention => try writer.writeAll("std.builtin.CallingConvention"),
+                .address_space => try writer.writeAll("std.builtin.AddressSpace"),
+                .float_mode => try writer.writeAll("std.builtin.FloatMode"),
+                .reduce_op => try writer.writeAll("std.builtin.ReduceOp"),
+                .call_modifier => try writer.writeAll("std.builtin.CallModifier"),
+                .prefetch_options => try writer.writeAll("std.builtin.PrefetchOptions"),
+                .export_options => try writer.writeAll("std.builtin.ExportOptions"),
+                .extern_options => try writer.writeAll("std.builtin.ExternOptions"),
+                .type_info => try writer.writeAll("std.builtin.Type"),
+
+                .generic_poison => unreachable,
             },
             .struct_type => |struct_type| {
                 if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {