Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow @src() outside of functions and allow @src().line at comptime #12847

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -13842,14 +13842,18 @@ fn zirBuiltinSrc(

const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data;
const src = LazySrcLoc.nodeOffset(extra.node);
const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{});
const fn_owner_decl = sema.mod.declPtr(func.owner_decl);

const func_name = blk: {
const func = sema.func orelse {
break :blk "";
};
const fn_owner_decl = sema.mod.declPtr(func.owner_decl);
break :blk std.mem.span(fn_owner_decl.name);
};
const func_name_val = blk: {
var anon_decl = try block.startAnonDecl(src);
defer anon_decl.deinit();
const name = std.mem.span(fn_owner_decl.name);
const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]);
const bytes = try anon_decl.arena().dupe(u8, func_name[0 .. func_name.len + 1]);
const new_decl = try anon_decl.finish(
try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len - 1),
try Value.Tag.bytes.create(anon_decl.arena(), bytes),
Expand All @@ -13861,7 +13865,7 @@ fn zirBuiltinSrc(
const file_name_val = blk: {
var anon_decl = try block.startAnonDecl(src);
defer anon_decl.deinit();
const relative_path = try fn_owner_decl.getFileScope().fullPath(sema.arena);
const relative_path = try block.getFileScope().fullPath(sema.arena);
const absolute_path = std.fs.realpathAlloc(sema.arena, relative_path) catch |err| {
return sema.fail(block, src, "failed to get absolute path of file '{s}': {s}", .{ relative_path, @errorName(err) });
};
Expand All @@ -13880,7 +13884,7 @@ fn zirBuiltinSrc(
// fn_name: [:0]const u8,
field_values[1] = func_name_val;
// line: u32
field_values[2] = try Value.Tag.runtime_int.create(sema.arena, extra.line + 1);
field_values[2] = try Value.Tag.int_u64.create(sema.arena, extra.line + 1);
// column: u32,
field_values[3] = try Value.Tag.int_u64.create(sema.arena, extra.column + 1);

Expand Down
21 changes: 19 additions & 2 deletions test/behavior/src.zig
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const src_outside_function = @src(); // do not move

fn doTheTest() !void {
const src = @src(); // do not move

try expect(src.line == 2);
try expect(src.line == 4);
try expect(src.column == 17);
try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));
try expect(std.mem.eql(u8, src.fn_name, "doTheTest"));
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);
Expand All @@ -20,3 +22,18 @@ test "@src" {

try doTheTest();
}

test "@src comptime, outside function" {
comptime {
if (builtin.zig_backend == .stage1) return error.SkipZigTest;

const src = src_outside_function;

try expect(src.line == 1);
try expect(src.column == 30);
try expect(std.mem.eql(u8, src.fn_name, ""));
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);
}
}
14 changes: 0 additions & 14 deletions test/cases/compile_errors/src_fields_runtime.zig

This file was deleted.

9 changes: 0 additions & 9 deletions test/cases/compile_errors/src_outside_function.zig

This file was deleted.