Commit cf87a1a7cf

Andrew Kelley <andrew@ziglang.org>
2024-08-07 23:05:55
language: add module name field to `@src`
closes #20963
1 parent ca012e5
Changed files (3)
lib
src
test
behavior
lib/std/builtin.zig
@@ -243,6 +243,9 @@ pub const AddressSpace = enum(u5) {
 /// This data structure is used by the Zig language code generation and
 /// therefore must be kept in sync with the compiler implementation.
 pub const SourceLocation = struct {
+    /// The name chosen when compiling. Not a file path.
+    module: [:0]const u8,
+    /// Relative to the root directory of its module.
     file: [:0]const u8,
     fn_name: [:0]const u8,
     line: u32,
src/Sema.zig
@@ -17769,11 +17769,12 @@ fn zirBuiltinSrc(
     defer tracy.end();
 
     const pt = sema.pt;
-    const mod = pt.zcu;
+    const zcu = pt.zcu;
     const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
-    const fn_owner_decl = mod.funcOwnerDeclPtr(sema.func_index);
-    const ip = &mod.intern_pool;
+    const fn_owner_decl = zcu.funcOwnerDeclPtr(sema.func_index);
+    const ip = &zcu.intern_pool;
     const gpa = sema.gpa;
+    const file_scope = fn_owner_decl.getFileScope(zcu);
 
     const func_name_val = v: {
         const func_name_len = fn_owner_decl.name.length(ip);
@@ -17799,8 +17800,34 @@ fn zirBuiltinSrc(
         } });
     };
 
+    const module_name_val = v: {
+        const module_name = file_scope.mod.fully_qualified_name;
+        const array_ty = try pt.intern(.{ .array_type = .{
+            .len = module_name.len,
+            .sentinel = .zero_u8,
+            .child = .u8_type,
+        } });
+        break :v try pt.intern(.{ .slice = .{
+            .ty = .slice_const_u8_sentinel_0_type,
+            .ptr = try pt.intern(.{ .ptr = .{
+                .ty = .manyptr_const_u8_sentinel_0_type,
+                .base_addr = .{ .anon_decl = .{
+                    .orig_ty = .slice_const_u8_sentinel_0_type,
+                    .val = try pt.intern(.{ .aggregate = .{
+                        .ty = array_ty,
+                        .storage = .{
+                            .bytes = try ip.getOrPutString(gpa, pt.tid, module_name, .maybe_embedded_nulls),
+                        },
+                    } }),
+                } },
+                .byte_offset = 0,
+            } }),
+            .len = (try pt.intValue(Type.usize, module_name.len)).toIntern(),
+        } });
+    };
+
     const file_name_val = v: {
-        const file_name = fn_owner_decl.getFileScope(mod).sub_file_path;
+        const file_name = file_scope.sub_file_path;
         const array_ty = try pt.intern(.{ .array_type = .{
             .len = file_name.len,
             .sentinel = .zero_u8,
@@ -17827,6 +17854,8 @@ fn zirBuiltinSrc(
 
     const src_loc_ty = try pt.getBuiltinType("SourceLocation");
     const fields = .{
+        // module: [:0]const u8,
+        module_name_val,
         // file: [:0]const u8,
         file_name_val,
         // fn_name: [:0]const u8,
test/behavior/src.zig
@@ -7,11 +7,13 @@ fn doTheTest() !void {
     try expect(std.mem.endsWith(u8, src.file, "src.zig"));
     try expect(src.fn_name[src.fn_name.len] == 0);
     try expect(src.file[src.file.len] == 0);
+    if (!std.mem.eql(u8, src.module, "test") and !std.mem.eql(u8, src.module, "root")) return error.TestFailure;
 }
 
 const std = @import("std");
 const builtin = @import("builtin");
 const expect = std.testing.expect;
+const expectEqualStrings = std.testing.expectEqualStrings;
 
 test "@src" {
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO