Commit 8f292431b0

Jacob Young <jacobly0@users.noreply.github.com>
2024-07-10 16:17:32
InternPool: fix undefined decl fully qualified name
This is now possible after moving `File.Index` to `*File` mapping into intern pool.
1 parent 3d2dfbe
src/Zcu/PerThread.zig
@@ -1896,7 +1896,7 @@ const ScanDeclIter = struct {
             const was_exported = decl.is_exported;
             assert(decl.kind == kind); // ZIR tracking should preserve this
             decl.name = decl_name;
-            decl.fqn = try namespace.internFullyQualifiedName(pt, decl_name);
+            decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
             decl.is_pub = declaration.flags.is_pub;
             decl.is_exported = declaration.flags.is_export;
             break :decl_index .{ was_exported, decl_index };
@@ -1906,7 +1906,7 @@ const ScanDeclIter = struct {
             const new_decl = zcu.declPtr(new_decl_index);
             new_decl.kind = kind;
             new_decl.name = decl_name;
-            new_decl.fqn = try namespace.internFullyQualifiedName(pt, decl_name);
+            new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
             new_decl.is_pub = declaration.flags.is_pub;
             new_decl.is_exported = declaration.flags.is_export;
             new_decl.zir_decl_index = tracked_inst.toOptional();
@@ -2279,8 +2279,8 @@ pub fn initNewAnonDecl(
     const new_decl = pt.zcu.declPtr(new_decl_index);
 
     new_decl.name = name;
-    new_decl.fqn = fqn.unwrap() orelse
-        try pt.zcu.namespacePtr(new_decl.src_namespace).internFullyQualifiedName(pt, name);
+    new_decl.fqn = fqn.unwrap() orelse try pt.zcu.namespacePtr(new_decl.src_namespace)
+        .internFullyQualifiedName(&pt.zcu.intern_pool, pt.zcu.gpa, pt.tid, name);
     new_decl.val = val;
     new_decl.alignment = .none;
     new_decl.@"linksection" = .none;
src/InternPool.zig
@@ -8030,6 +8030,8 @@ fn finishFuncInstance(
     decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
         fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
     }, .no_embedded_nulls);
+    decl.fqn = try ip.namespacePtr(fn_owner_decl.src_namespace)
+        .internFullyQualifiedName(ip, gpa, tid, decl.name);
 }
 
 pub const EnumTypeInit = struct {
src/Sema.zig
@@ -9737,9 +9737,6 @@ fn funcCommon(
             .generic_owner = sema.generic_owner,
             .comptime_args = sema.comptime_args,
         });
-        const func_decl = mod.declPtr(ip.indexToKey(func_index).func.owner_decl);
-        func_decl.fqn =
-            try ip.namespacePtr(func_decl.src_namespace).internFullyQualifiedName(pt, func_decl.name);
         return finishFunc(
             sema,
             block,
src/Type.zig
@@ -337,7 +337,7 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
                 try writer.print("{}", .{decl.fqn.fmt(ip)});
             } else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| {
                 const namespace = mod.namespacePtr(namespace_index);
-                try namespace.renderFullyQualifiedName(mod, .empty, writer);
+                try namespace.renderFullyQualifiedName(ip, .empty, writer);
             } else {
                 try writer.writeAll("@TypeOf(.{})");
             }
src/Zcu.zig
@@ -628,23 +628,27 @@ pub const Namespace = struct {
         return zcu.fileByIndex(ns.file_scope);
     }
 
+    pub fn fileScopeIp(ns: Namespace, ip: *InternPool) *File {
+        return ip.filePtr(ns.file_scope);
+    }
+
     // This renders e.g. "std.fs.Dir.OpenOptions"
     pub fn renderFullyQualifiedName(
         ns: Namespace,
-        zcu: *Zcu,
+        ip: *InternPool,
         name: InternPool.NullTerminatedString,
         writer: anytype,
     ) @TypeOf(writer).Error!void {
         if (ns.parent.unwrap()) |parent| {
-            try zcu.namespacePtr(parent).renderFullyQualifiedName(
-                zcu,
-                zcu.declPtr(ns.decl_index).name,
+            try ip.namespacePtr(parent).renderFullyQualifiedName(
+                ip,
+                ip.declPtr(ns.decl_index).name,
                 writer,
             );
         } else {
-            try ns.fileScope(zcu).renderFullyQualifiedName(writer);
+            try ns.fileScopeIp(ip).renderFullyQualifiedName(writer);
         }
-        if (name != .empty) try writer.print(".{}", .{name.fmt(&zcu.intern_pool)});
+        if (name != .empty) try writer.print(".{}", .{name.fmt(ip)});
     }
 
     /// This renders e.g. "std/fs.zig:Dir.OpenOptions"
@@ -670,44 +674,43 @@ pub const Namespace = struct {
 
     pub fn internFullyQualifiedName(
         ns: Namespace,
-        pt: Zcu.PerThread,
+        ip: *InternPool,
+        gpa: Allocator,
+        tid: Zcu.PerThread.Id,
         name: InternPool.NullTerminatedString,
     ) !InternPool.NullTerminatedString {
-        const zcu = pt.zcu;
-        const ip = &zcu.intern_pool;
-
-        const gpa = zcu.gpa;
-        const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
+        const strings = ip.getLocal(tid).getMutableStrings(gpa);
         // Protects reads of interned strings from being reallocated during the call to
         // renderFullyQualifiedName.
         const slice = try strings.addManyAsSlice(count: {
             var count: usize = name.length(ip) + 1;
             var cur_ns = &ns;
             while (true) {
-                const decl = zcu.declPtr(cur_ns.decl_index);
-                cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse {
-                    count += ns.fileScope(zcu).fullyQualifiedNameLen();
+                const decl = ip.declPtr(cur_ns.decl_index);
+                cur_ns = ip.namespacePtr(cur_ns.parent.unwrap() orelse {
+                    count += ns.fileScopeIp(ip).fullyQualifiedNameLen();
                     break :count count;
                 });
                 count += decl.name.length(ip) + 1;
             }
         });
         var fbs = std.io.fixedBufferStream(slice[0]);
-        ns.renderFullyQualifiedName(zcu, name, fbs.writer()) catch unreachable;
+        ns.renderFullyQualifiedName(ip, name, fbs.writer()) catch unreachable;
         assert(fbs.pos == slice[0].len);
 
         // Sanitize the name for nvptx which is more restrictive.
         // TODO This should be handled by the backend, not the frontend. Have a
         // look at how the C backend does it for inspiration.
-        const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
-        if (cpu_arch.isNvptx()) {
-            for (slice[0]) |*byte| switch (byte.*) {
-                '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
-                else => {},
-            };
-        }
-
-        return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls);
+        // FIXME This has bitrotted and is no longer able to be implemented here.
+        //const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
+        //if (cpu_arch.isNvptx()) {
+        //    for (slice[0]) |*byte| switch (byte.*) {
+        //        '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
+        //        else => {},
+        //    };
+        //}
+
+        return ip.getOrPutTrailingString(gpa, tid, @intCast(slice[0].len), .no_embedded_nulls);
     }
 
     pub fn getType(ns: Namespace, zcu: *Zcu) Type {