Zcu: rework source locations

`LazySrcLoc` now stores a reference to the "base AST node" to which it
is relative. The previous tagged union is `LazySrcLoc.Offset`. To make
working with this structure convenient, `Sema.Block` contains a
convenience `src` method which takes an `Offset` and returns a
`LazySrcLoc`.

The "base node" of a source location is no longer given by a `Decl`, but
rather a `TrackedInst` representing either a `declaration`,
`struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl`. This is a
more appropriate model, and removes an unnecessary responsibility from
`Decl` in preparation for the upcoming refactor which will split it into
`Nav` and `Cau`.

As a part of these `Decl` reworks, the `src_node` field is eliminated.
This change aids incremental compilation, and simplifies `Decl`. In some
cases -- particularly in backends -- the source location of a
declaration is desired. This was previously `Decl.srcLoc` and worked for
any `Decl`. Now, it is `Decl.navSrcLoc` in reference to the upcoming
refactor, since the set of `Decl`s this works for precisely corresponds
to what will in future become a `Nav` -- that is, source-level
declarations and generic function instantiations, but *not* type owner
Decls.

This commit introduces more tags to `LazySrcLoc.Offset` so as to
eliminate the concept of `error.NeededSourceLocation`. Now, `.unneeded`
should only be used to assert that an error path is unreachable. In the
future, uses of `.unneeded` can probably be replaced with `undefined`.

The `src_decl` field of `Sema.Block` no longer has a role in type
resolution. Its main remaining purpose is to handle namespacing of type
names. It will be eliminated entirely in a future commit to remove
another undue responsibility from `Decl`.

It is worth noting that in future, the `Zcu.SrcLoc` type should probably
be eliminated entirely in favour of storing `Zcu.LazySrcLoc` values.
This is because `Zcu.SrcLoc` is not valid across incremental updates,
and we want to be able to reuse error messages from previous updates
even if the source file in question changed. The error reporting logic
should instead simply resolve the location from the `LazySrcLoc` on the
fly.
This commit is contained in:
mlugg 2024-06-14 23:05:39 +01:00
parent 07a24bec9a
commit 1eaeb4a0a8
No known key found for this signature in database
GPG Key ID: 3F5B7DCCBF4AF02E
34 changed files with 2447 additions and 2868 deletions

View File

@ -2639,7 +2639,7 @@ fn reportMultiModuleErrors(mod: *Module) !void {
.root => |pkg| blk: {
break :blk try Module.ErrorMsg.init(
mod.gpa,
.{ .file_scope = file, .parent_decl_node = 0, .lazy = .entire_file },
.{ .file_scope = file, .base_node = 0, .lazy = .entire_file },
"root of module {s}",
.{pkg.fully_qualified_name},
);
@ -2651,7 +2651,7 @@ fn reportMultiModuleErrors(mod: *Module) !void {
if (omitted > 0) {
notes[num_notes] = try Module.ErrorMsg.init(
mod.gpa,
.{ .file_scope = file, .parent_decl_node = 0, .lazy = .entire_file },
.{ .file_scope = file, .base_node = 0, .lazy = .entire_file },
"{} more references omitted",
.{omitted},
);
@ -2660,7 +2660,7 @@ fn reportMultiModuleErrors(mod: *Module) !void {
const err = try Module.ErrorMsg.create(
mod.gpa,
.{ .file_scope = file, .parent_decl_node = 0, .lazy = .entire_file },
.{ .file_scope = file, .base_node = 0, .lazy = .entire_file },
"file exists in multiple modules",
.{},
);
@ -3040,29 +3040,26 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
}
}
if (comp.module) |module| {
if (bundle.root_list.items.len == 0 and module.compile_log_decls.count() != 0) {
const keys = module.compile_log_decls.keys();
const values = module.compile_log_decls.values();
if (comp.module) |zcu| {
if (bundle.root_list.items.len == 0 and zcu.compile_log_decls.count() != 0) {
const values = zcu.compile_log_decls.values();
// First one will be the error; subsequent ones will be notes.
const err_decl = module.declPtr(keys[0]);
const src_loc = err_decl.nodeOffsetSrcLoc(values[0], module);
const err_msg = Module.ErrorMsg{
const src_loc = values[0].src().upgrade(zcu);
const err_msg: Module.ErrorMsg = .{
.src_loc = src_loc,
.msg = "found compile log statement",
.notes = try gpa.alloc(Module.ErrorMsg, module.compile_log_decls.count() - 1),
.notes = try gpa.alloc(Module.ErrorMsg, zcu.compile_log_decls.count() - 1),
};
defer gpa.free(err_msg.notes);
for (keys[1..], 0..) |key, i| {
const note_decl = module.declPtr(key);
err_msg.notes[i] = .{
.src_loc = note_decl.nodeOffsetSrcLoc(values[i + 1], module),
for (values[1..], err_msg.notes) |src_info, *note| {
note.* = .{
.src_loc = src_info.src().upgrade(zcu),
.msg = "also here",
};
}
try addModuleErrorMsg(module, &bundle, err_msg);
try addModuleErrorMsg(zcu, &bundle, err_msg);
}
}
@ -3492,7 +3489,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
try module.failed_decls.ensureUnusedCapacity(gpa, 1);
module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
gpa,
decl.srcLoc(module),
decl.navSrcLoc(module).upgrade(module),
"unable to update line number: {s}",
.{@errorName(err)},
));
@ -3993,7 +3990,7 @@ fn workerAstGenFile(
if (!res.is_pkg) {
res.file.addReference(mod.*, .{ .import = .{
.file_scope = file,
.parent_decl_node = 0,
.base_node = 0,
.lazy = .{ .token_abs = item.data.token },
} }) catch continue;
}
@ -4370,7 +4367,7 @@ fn reportRetryableAstGenError(
const src_loc: Module.SrcLoc = switch (src) {
.root => .{
.file_scope = file,
.parent_decl_node = 0,
.base_node = 0,
.lazy = .entire_file,
},
.import => |info| blk: {
@ -4378,7 +4375,7 @@ fn reportRetryableAstGenError(
break :blk .{
.file_scope = importing_file,
.parent_decl_node = 0,
.base_node = 0,
.lazy = .{ .token_abs = info.import_tok },
};
},

View File

@ -101,8 +101,11 @@ pub const TrackedInst = extern struct {
}
pub const Index = enum(u32) {
_,
pub fn resolveFull(i: TrackedInst.Index, ip: *const InternPool) TrackedInst {
return ip.tracked_insts.keys()[@intFromEnum(i)];
}
pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Zir.Inst.Index {
return ip.tracked_insts.keys()[@intFromEnum(i)].inst;
return i.resolveFull(ip).inst;
}
pub fn toOptional(i: TrackedInst.Index) Optional {
return @enumFromInt(@intFromEnum(i));
@ -6954,7 +6957,6 @@ fn finishFuncInstance(
const decl_index = try ip.createDecl(gpa, .{
.name = undefined,
.src_namespace = fn_owner_decl.src_namespace,
.src_node = fn_owner_decl.src_node,
.src_line = fn_owner_decl.src_line,
.has_tv = true,
.owns_tv = true,

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ const Type = @import("type.zig").Type;
const Value = @import("Value.zig");
const Module = @import("Module.zig");
const RangeSet = @This();
const SwitchProngSrc = @import("Module.zig").SwitchProngSrc;
const LazySrcLoc = @import("Module.zig").LazySrcLoc;
ranges: std.ArrayList(Range),
module: *Module,
@ -15,7 +15,7 @@ module: *Module,
pub const Range = struct {
first: InternPool.Index,
last: InternPool.Index,
src: SwitchProngSrc,
src: LazySrcLoc,
};
pub fn init(allocator: std.mem.Allocator, module: *Module) RangeSet {
@ -33,8 +33,8 @@ pub fn add(
self: *RangeSet,
first: InternPool.Index,
last: InternPool.Index,
src: SwitchProngSrc,
) !?SwitchProngSrc {
src: LazySrcLoc,
) !?LazySrcLoc {
const mod = self.module;
const ip = &mod.intern_pool;

File diff suppressed because it is too large Load Diff

View File

@ -1025,18 +1025,18 @@ fn checkComptimeVarStore(
if (@intFromEnum(runtime_index) < @intFromEnum(block.runtime_index)) {
if (block.runtime_cond) |cond_src| {
const msg = msg: {
const msg = try sema.errMsg(block, src, "store to comptime variable depends on runtime condition", .{});
const msg = try sema.errMsg(src, "store to comptime variable depends on runtime condition", .{});
errdefer msg.destroy(sema.gpa);
try sema.mod.errNoteNonLazy(cond_src, msg, "runtime condition here", .{});
try sema.errNote(cond_src, msg, "runtime condition here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
}
if (block.runtime_loop) |loop_src| {
const msg = msg: {
const msg = try sema.errMsg(block, src, "cannot store to comptime variable in non-inline loop", .{});
const msg = try sema.errMsg(src, "cannot store to comptime variable in non-inline loop", .{});
errdefer msg.destroy(sema.gpa);
try sema.mod.errNoteNonLazy(loop_src, msg, "non-inline loop here", .{});
try sema.errNote(loop_src, msg, "non-inline loop here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);

View File

@ -4014,7 +4014,6 @@ pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator.
return ptr_val.pointerDerivationAdvanced(arena, zcu, null) catch |err| switch (err) {
error.OutOfMemory => |e| return e,
error.AnalysisFail,
error.NeededSourceLocation,
error.GenericPoison,
error.ComptimeReturn,
error.ComptimeBreak,

View File

@ -16,7 +16,6 @@ const Decl = Module.Decl;
const Type = @import("../../type.zig").Type;
const Value = @import("../../Value.zig");
const Compilation = @import("../../Compilation.zig");
const LazySrcLoc = Module.LazySrcLoc;
const link = @import("../../link.zig");
const Air = @import("../../Air.zig");
const Liveness = @import("../../Liveness.zig");
@ -766,7 +765,7 @@ pub fn deinit(func: *CodeGen) void {
/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig
fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {
const mod = func.bin_file.base.comp.module.?;
const src_loc = func.decl.srcLoc(mod);
const src_loc = func.decl.navSrcLoc(mod).upgrade(mod);
func.err_msg = try Module.ErrorMsg.create(func.gpa, src_loc, fmt, args);
return error.CodegenFail;
}
@ -3123,7 +3122,7 @@ fn lowerAnonDeclRef(
}
const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.srcLoc(mod));
const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.navSrcLoc(mod).upgrade(mod));
switch (res) {
.ok => {},
.fail => |em| {

View File

@ -257,7 +257,7 @@ fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
const comp = emit.bin_file.base.comp;
const zcu = comp.module.?;
const gpa = comp.gpa;
emit.error_msg = try Module.ErrorMsg.create(gpa, zcu.declPtr(emit.decl_index).srcLoc(zcu), format, args);
emit.error_msg = try Module.ErrorMsg.create(gpa, zcu.declPtr(emit.decl_index).navSrcLoc(zcu).upgrade(zcu), format, args);
return error.EmitFail;
}

View File

@ -13,7 +13,6 @@ const Type = @import("../type.zig").Type;
const C = link.File.C;
const Decl = Zcu.Decl;
const trace = @import("../tracy.zig").trace;
const LazySrcLoc = Zcu.LazySrcLoc;
const Air = @import("../Air.zig");
const Liveness = @import("../Liveness.zig");
const InternPool = @import("../InternPool.zig");
@ -638,7 +637,7 @@ pub const DeclGen = struct {
const zcu = dg.zcu;
const decl_index = dg.pass.decl;
const decl = zcu.declPtr(decl_index);
const src_loc = decl.srcLoc(zcu);
const src_loc = decl.navSrcLoc(zcu).upgrade(zcu);
dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);
return error.AnalysisFail;
}

View File

@ -22,7 +22,6 @@ const Air = @import("../Air.zig");
const Liveness = @import("../Liveness.zig");
const Value = @import("../Value.zig");
const Type = @import("../type.zig").Type;
const LazySrcLoc = Zcu.LazySrcLoc;
const x86_64_abi = @import("../arch/x86_64/abi.zig");
const wasm_c_abi = @import("../arch/wasm/abi.zig");
const aarch64_c_abi = @import("../arch/aarch64/abi.zig");
@ -2066,7 +2065,7 @@ pub const Object = struct {
try o.builder.metadataString(name),
file,
scope,
owner_decl.src_node + 1, // Line
owner_decl.src_line + 1, // Line
try o.lowerDebugType(int_ty),
ty.abiSize(mod) * 8,
(ty.abiAlignment(mod).toByteUnits() orelse 0) * 8,
@ -2236,7 +2235,7 @@ pub const Object = struct {
try o.builder.metadataString(name),
try o.getDebugFile(mod.namespacePtr(owner_decl.src_namespace).file_scope),
try o.namespaceToDebugScope(owner_decl.src_namespace),
owner_decl.src_node + 1, // Line
owner_decl.src_line + 1, // Line
.none, // Underlying type
0, // Size
0, // Align
@ -4728,7 +4727,7 @@ pub const DeclGen = struct {
const o = dg.object;
const gpa = o.gpa;
const mod = o.module;
const src_loc = dg.decl.srcLoc(mod);
const src_loc = dg.decl.navSrcLoc(mod).upgrade(mod);
dg.err_msg = try Module.ErrorMsg.create(gpa, src_loc, "TODO (LLVM): " ++ format, args);
return error.CodegenFail;
}

View File

@ -9,7 +9,6 @@ const Module = @import("../Module.zig");
const Decl = Module.Decl;
const Type = @import("../type.zig").Type;
const Value = @import("../Value.zig");
const LazySrcLoc = Module.LazySrcLoc;
const Air = @import("../Air.zig");
const Liveness = @import("../Liveness.zig");
const InternPool = @import("../InternPool.zig");
@ -414,7 +413,7 @@ const DeclGen = struct {
pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
@setCold(true);
const mod = self.module;
const src_loc = self.module.declPtr(self.decl_index).srcLoc(mod);
const src_loc = self.module.declPtr(self.decl_index).navSrcLoc(mod).upgrade(mod);
assert(self.error_msg == null);
self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, format, args);
return error.CodegenFail;
@ -6433,7 +6432,7 @@ const DeclGen = struct {
// TODO: Translate proper error locations.
assert(as.errors.items.len != 0);
assert(self.error_msg == null);
const src_loc = self.module.declPtr(self.decl_index).srcLoc(mod);
const src_loc = self.module.declPtr(self.decl_index).navSrcLoc(mod).upgrade(mod);
self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
const notes = try self.module.gpa.alloc(Module.ErrorMsg, as.errors.items.len);

View File

@ -10,6 +10,7 @@ const native_os = builtin.os.tag;
const Module = @import("Module.zig");
const Sema = @import("Sema.zig");
const InternPool = @import("InternPool.zig");
const Zir = std.zig.Zir;
const Decl = Module.Decl;
@ -76,18 +77,19 @@ fn dumpStatusReport() !void {
const stderr = io.getStdErr().writer();
const block: *Sema.Block = anal.block;
const mod = anal.sema.mod;
const block_src_decl = mod.declPtr(block.src_decl);
const file, const src_base_node = Module.LazySrcLoc.resolveBaseNode(block.src_base_inst, mod);
try stderr.writeAll("Analyzing ");
try writeFullyQualifiedDeclWithFile(mod, block_src_decl, stderr);
try writeFullyQualifiedDeclWithFile(mod, block.src_decl, stderr);
try stderr.writeAll("\n");
print_zir.renderInstructionContext(
allocator,
anal.body,
anal.body_index,
mod.namespacePtr(block.namespace).file_scope,
block_src_decl.src_node,
file,
src_base_node,
6, // indent
stderr,
) catch |err| switch (err) {
@ -95,21 +97,21 @@ fn dumpStatusReport() !void {
else => |e| return e,
};
try stderr.writeAll(" For full context, use the command\n zig ast-check -t ");
try writeFilePath(mod.namespacePtr(block.namespace).file_scope, stderr);
try writeFilePath(file, stderr);
try stderr.writeAll("\n\n");
var parent = anal.parent;
while (parent) |curr| {
fba.reset();
try stderr.writeAll(" in ");
const curr_block_src_decl = mod.declPtr(curr.block.src_decl);
try writeFullyQualifiedDeclWithFile(mod, curr_block_src_decl, stderr);
const cur_block_file, const cur_block_src_base_node = Module.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, mod);
try writeFullyQualifiedDeclWithFile(mod, curr.block.src_decl, stderr);
try stderr.writeAll("\n > ");
print_zir.renderSingleInstruction(
allocator,
curr.body[curr.body_index],
mod.namespacePtr(curr.block.namespace).file_scope,
curr_block_src_decl.src_node,
cur_block_file,
cur_block_src_base_node,
6, // indent
stderr,
) catch |err| switch (err) {
@ -138,7 +140,8 @@ fn writeFilePath(file: *Module.File, writer: anytype) !void {
try writer.writeAll(file.sub_file_path);
}
fn writeFullyQualifiedDeclWithFile(mod: *Module, decl: *Decl, writer: anytype) !void {
fn writeFullyQualifiedDeclWithFile(mod: *Module, decl_index: InternPool.DeclIndex, writer: anytype) !void {
const decl = mod.declPtr(decl_index);
try writeFilePath(decl.getFileScope(mod), writer);
try writer.writeAll(": ");
try decl.renderFullyQualifiedDebugName(mod, writer);

View File

@ -1144,7 +1144,7 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:
const res = try codegen.generateFunction(
&self.base,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
func_index,
air,
liveness,
@ -1181,7 +1181,7 @@ pub fn lowerUnnamedConst(self: *Coff, val: Value, decl_index: InternPool.DeclInd
const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
defer gpa.free(sym_name);
const ty = val.typeOf(mod);
const atom_index = switch (try self.lowerConst(sym_name, val, ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) {
const atom_index = switch (try self.lowerConst(sym_name, val, ty.abiAlignment(mod), self.rdata_section_index.?, decl.navSrcLoc(mod).upgrade(mod))) {
.ok => |atom_index| atom_index,
.fail => |em| {
decl.analysis = .codegen_failure;
@ -1272,7 +1272,7 @@ pub fn updateDecl(
defer code_buffer.deinit();
const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), decl_val, &code_buffer, .none, .{
const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod).upgrade(mod), decl_val, &code_buffer, .none, .{
.parent_atom_index = atom.getSymbolIndex().?,
});
const code = switch (res) {
@ -1313,12 +1313,12 @@ fn updateLazySymbolAtom(
const atom = self.getAtomPtr(atom_index);
const local_sym_index = atom.getSymbolIndex().?;
const src = if (sym.ty.getOwnerDeclOrNull(mod)) |owner_decl|
mod.declPtr(owner_decl).srcLoc(mod)
const src = if (sym.ty.srcLocOrNull(mod)) |src|
src.upgrade(mod)
else
Module.SrcLoc{
.file_scope = undefined,
.parent_decl_node = undefined,
.base_node = undefined,
.lazy = .unneeded,
};
const res = try codegen.generateLazySymbol(

View File

@ -1072,7 +1072,7 @@ pub fn updateFunc(
const res = if (decl_state) |*ds|
try codegen.generateFunction(
&elf_file.base,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
func_index,
air,
liveness,
@ -1082,7 +1082,7 @@ pub fn updateFunc(
else
try codegen.generateFunction(
&elf_file.base,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
func_index,
air,
liveness,
@ -1156,13 +1156,13 @@ pub fn updateDecl(
// TODO implement .debug_info for global variables
const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
const res = if (decl_state) |*ds|
try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), decl_val, &code_buffer, .{
try codegen.generateSymbol(&elf_file.base, decl.navSrcLoc(mod).upgrade(mod), decl_val, &code_buffer, .{
.dwarf = ds,
}, .{
.parent_atom_index = sym_index,
})
else
try codegen.generateSymbol(&elf_file.base, decl.srcLoc(mod), decl_val, &code_buffer, .none, .{
try codegen.generateSymbol(&elf_file.base, decl.navSrcLoc(mod).upgrade(mod), decl_val, &code_buffer, .none, .{
.parent_atom_index = sym_index,
});
@ -1219,12 +1219,12 @@ fn updateLazySymbol(
break :blk try self.strtab.insert(gpa, name);
};
const src = if (sym.ty.getOwnerDeclOrNull(mod)) |owner_decl|
mod.declPtr(owner_decl).srcLoc(mod)
const src = if (sym.ty.srcLocOrNull(mod)) |src|
src.upgrade(mod)
else
Module.SrcLoc{
.file_scope = undefined,
.parent_decl_node = undefined,
.base_node = undefined,
.lazy = .unneeded,
};
const res = try codegen.generateLazySymbol(
@ -1304,7 +1304,7 @@ pub fn lowerUnnamedConst(
val,
ty.abiAlignment(mod),
elf_file.zig_data_rel_ro_section_index.?,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
)) {
.ok => |sym_index| sym_index,
.fail => |em| {

View File

@ -682,7 +682,7 @@ pub fn updateFunc(
const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
const res = try codegen.generateFunction(
&macho_file.base,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
func_index,
air,
liveness,
@ -756,7 +756,7 @@ pub fn updateDecl(
const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
const res = try codegen.generateSymbol(&macho_file.base, decl.srcLoc(mod), decl_val, &code_buffer, dio, .{
const res = try codegen.generateSymbol(&macho_file.base, decl.navSrcLoc(mod).upgrade(mod), decl_val, &code_buffer, dio, .{
.parent_atom_index = sym_index,
});
@ -1104,7 +1104,7 @@ pub fn lowerUnnamedConst(
val,
val.typeOf(mod).abiAlignment(mod),
macho_file.zig_const_sect_index.?,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
)) {
.ok => |sym_index| sym_index,
.fail => |em| {
@ -1294,12 +1294,12 @@ fn updateLazySymbol(
break :blk try self.strtab.insert(gpa, name);
};
const src = if (lazy_sym.ty.getOwnerDeclOrNull(mod)) |owner_decl|
mod.declPtr(owner_decl).srcLoc(mod)
const src = if (lazy_sym.ty.srcLocOrNull(mod)) |src|
src.upgrade(mod)
else
Module.SrcLoc{
.file_scope = undefined,
.parent_decl_node = undefined,
.base_node = undefined,
.lazy = .unneeded,
};
const res = try codegen.generateLazySymbol(

View File

@ -433,7 +433,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
const res = try codegen.generateFunction(
&self.base,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
func_index,
air,
liveness,
@ -499,7 +499,7 @@ pub fn lowerUnnamedConst(self: *Plan9, val: Value, decl_index: InternPool.DeclIn
};
self.syms.items[info.sym_index.?] = sym;
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), val, &code_buffer, .{
const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod).upgrade(mod), val, &code_buffer, .{
.none = {},
}, .{
.parent_atom_index = new_atom_idx,
@ -538,7 +538,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex)
defer code_buffer.deinit();
const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
// TODO we need the symbol index for symbol in the table of locals for the containing atom
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), decl_val, &code_buffer, .{ .none = {} }, .{
const res = try codegen.generateSymbol(&self.base, decl.navSrcLoc(mod).upgrade(mod), decl_val, &code_buffer, .{ .none = {} }, .{
.parent_atom_index = @as(Atom.Index, @intCast(atom_idx)),
});
const code = switch (res) {
@ -1020,7 +1020,7 @@ fn addDeclExports(
{
try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
gpa,
mod.declPtr(decl_index).srcLoc(mod),
mod.declPtr(decl_index).navSrcLoc(mod).upgrade(mod),
"plan9 does not support extra sections",
.{},
));
@ -1212,12 +1212,12 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
self.syms.items[self.getAtomPtr(atom_index).sym_index.?] = symbol;
// generate the code
const src = if (sym.ty.getOwnerDeclOrNull(mod)) |owner_decl|
mod.declPtr(owner_decl).srcLoc(mod)
const src = if (sym.ty.srcLocOrNull(mod)) |src|
src.upgrade(mod)
else
Module.SrcLoc{
.file_scope = undefined,
.parent_decl_node = undefined,
.base_node = undefined,
.lazy = .unneeded,
};
const res = try codegen.generateLazySymbol(

View File

@ -269,7 +269,7 @@ pub fn updateDecl(
const res = try codegen.generateSymbol(
&wasm_file.base,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
val,
&code_writer,
.none,
@ -308,7 +308,7 @@ pub fn updateFunc(
defer code_writer.deinit();
const result = try codegen.generateFunction(
&wasm_file.base,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
func_index,
air,
liveness,
@ -484,7 +484,7 @@ pub fn lowerUnnamedConst(zig_object: *ZigObject, wasm_file: *Wasm, val: Value, d
});
defer gpa.free(name);
switch (try zig_object.lowerConst(wasm_file, name, val, decl.srcLoc(mod))) {
switch (try zig_object.lowerConst(wasm_file, name, val, decl.navSrcLoc(mod).upgrade(mod))) {
.ok => |atom_index| {
try wasm_file.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
return @intFromEnum(wasm_file.getAtom(atom_index).sym_index);
@ -867,7 +867,7 @@ pub fn updateExports(
if (exp.opts.section.toSlice(&mod.intern_pool)) |section| {
try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
gpa,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
"Unimplemented: ExportOptions.section '{s}'",
.{section},
));
@ -900,7 +900,7 @@ pub fn updateExports(
.link_once => {
try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
gpa,
decl.srcLoc(mod),
decl.navSrcLoc(mod).upgrade(mod),
"Unimplemented: LinkOnce",
.{},
));

View File

@ -32,7 +32,7 @@ pub fn format(
return print(ctx.val, writer, ctx.depth, ctx.mod, ctx.opt_sema) catch |err| switch (err) {
error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
error.ComptimeBreak, error.ComptimeReturn => unreachable,
error.AnalysisFail, error.NeededSourceLocation => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully
error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `opt_sema` more fully
else => |e| return e,
};
}

View File

@ -48,12 +48,11 @@ pub fn renderAsTextToFile(
const item = scope_file.zir.extraData(Zir.Inst.Imports.Item, extra_index);
extra_index = item.end;
const src: LazySrcLoc = .{ .token_abs = item.data.token };
const import_path = scope_file.zir.nullTerminatedString(item.data.name);
try stream.print(" @import(\"{}\") ", .{
std.zig.fmtEscapes(import_path),
});
try writer.writeSrc(stream, src);
try writer.writeSrcTokAbs(stream, item.data.token);
try stream.writeAll("\n");
}
}
@ -188,7 +187,7 @@ const Writer = struct {
} = .{},
fn relativeToNodeIndex(self: *Writer, offset: i32) Ast.Node.Index {
return @as(Ast.Node.Index, @bitCast(offset + @as(i32, @bitCast(self.parent_decl_node))));
return @bitCast(offset + @as(i32, @bitCast(self.parent_decl_node)));
}
fn writeInstToStream(
@ -578,10 +577,9 @@ const Writer = struct {
.work_group_id,
=> {
const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
const src = LazySrcLoc.nodeOffset(inst_data.node);
try self.writeInstRef(stream, inst_data.operand);
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, inst_data.node);
},
.builtin_extern,
@ -592,12 +590,11 @@ const Writer = struct {
.c_va_arg,
=> {
const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
const src = LazySrcLoc.nodeOffset(inst_data.node);
try self.writeInstRef(stream, inst_data.lhs);
try stream.writeAll(", ");
try self.writeInstRef(stream, inst_data.rhs);
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, inst_data.node);
},
.builtin_async_call => try self.writeBuiltinAsyncCall(stream, extended),
@ -612,9 +609,8 @@ const Writer = struct {
}
fn writeExtNode(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const src = LazySrcLoc.nodeOffset(@as(i32, @bitCast(extended.operand)));
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, @bitCast(extended.operand));
}
fn writeArrayInitElemType(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
@ -654,7 +650,7 @@ const Writer = struct {
const extra = self.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;
try self.writeInstRef(stream, extra.operand);
try stream.print(", {d}) (destructure=", .{extra.expect_len});
try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.destructure_node));
try self.writeSrcNode(stream, extra.destructure_node);
try stream.writeAll(") ");
try self.writeSrcNode(stream, inst_data.src_node);
}
@ -729,7 +725,7 @@ const Writer = struct {
try stream.writeAll(")");
}
try stream.writeAll(") ");
try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.data.src_node));
try self.writeSrcNode(stream, extra.data.src_node);
}
fn writeInt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
@ -868,7 +864,7 @@ const Writer = struct {
try stream.writeAll(", ");
try self.writeInstRef(stream, extra.b);
try stream.writeAll(") ");
try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.node));
try self.writeSrcNode(stream, extra.node);
}
fn writeMulAdd(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
@ -926,7 +922,7 @@ const Writer = struct {
try stream.writeAll(", ");
try self.writeInstRef(stream, extra.args);
try stream.writeAll(") ");
try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.node));
try self.writeSrcNode(stream, extra.node);
}
fn writeParam(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
@ -1056,7 +1052,6 @@ const Writer = struct {
fn writeCmpxchg(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const extra = self.code.extraData(Zir.Inst.Cmpxchg, extended.operand).data;
const src = LazySrcLoc.nodeOffset(extra.node);
try self.writeInstRef(stream, extra.ptr);
try stream.writeAll(", ");
@ -1068,14 +1063,13 @@ const Writer = struct {
try stream.writeAll(", ");
try self.writeInstRef(stream, extra.failure_order);
try stream.writeAll(") ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, extra.node);
}
fn writePtrCastFull(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
const src = LazySrcLoc.nodeOffset(extra.node);
if (flags.ptr_cast) try stream.writeAll("ptr_cast, ");
if (flags.align_cast) try stream.writeAll("align_cast, ");
if (flags.addrspace_cast) try stream.writeAll("addrspace_cast, ");
@ -1085,19 +1079,18 @@ const Writer = struct {
try stream.writeAll(", ");
try self.writeInstRef(stream, extra.rhs);
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, extra.node);
}
fn writePtrCastNoDest(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
const src = LazySrcLoc.nodeOffset(extra.node);
if (flags.const_cast) try stream.writeAll("const_cast, ");
if (flags.volatile_cast) try stream.writeAll("volatile_cast, ");
try self.writeInstRef(stream, extra.operand);
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, extra.node);
}
fn writeAtomicLoad(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
@ -1183,7 +1176,6 @@ const Writer = struct {
fn writeNodeMultiOp(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const extra = self.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
const src = LazySrcLoc.nodeOffset(extra.data.src_node);
const operands = self.code.refSlice(extra.end, extended.small);
for (operands, 0..) |operand, i| {
@ -1191,7 +1183,7 @@ const Writer = struct {
try self.writeInstRef(stream, operand);
}
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, extra.data.src_node);
}
fn writeInstNode(
@ -1212,7 +1204,6 @@ const Writer = struct {
tmpl_is_expr: bool,
) !void {
const extra = self.code.extraData(Zir.Inst.Asm, extended.operand);
const src = LazySrcLoc.nodeOffset(extra.data.src_node);
const outputs_len = @as(u5, @truncate(extended.small));
const inputs_len = @as(u5, @truncate(extended.small >> 5));
const clobbers_len = @as(u5, @truncate(extended.small >> 10));
@ -1283,18 +1274,17 @@ const Writer = struct {
}
}
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, extra.data.src_node);
}
fn writeOverflowArithmetic(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
const src = LazySrcLoc.nodeOffset(extra.node);
try self.writeInstRef(stream, extra.lhs);
try stream.writeAll(", ");
try self.writeInstRef(stream, extra.rhs);
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, extra.node);
}
fn writeCall(
@ -2287,9 +2277,8 @@ const Writer = struct {
inst: Zir.Inst.Index,
) (@TypeOf(stream).Error || error{OutOfMemory})!void {
const src_node = self.code.instructions.items(.data)[@intFromEnum(inst)].node;
const src = LazySrcLoc.nodeOffset(src_node);
try stream.writeAll(") ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, src_node);
}
fn writeStrTok(
@ -2507,7 +2496,6 @@ const Writer = struct {
fn writeAllocExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand);
const small = @as(Zir.Inst.AllocExtended.Small, @bitCast(extended.small));
const src = LazySrcLoc.nodeOffset(extra.data.src_node);
var extra_index: usize = extra.end;
const type_inst: Zir.Inst.Ref = if (!small.has_type) .none else blk: {
@ -2525,7 +2513,7 @@ const Writer = struct {
try self.writeOptionalInstRef(stream, ",ty=", type_inst);
try self.writeOptionalInstRef(stream, ",align=", align_inst);
try stream.writeAll(")) ");
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, extra.data.src_node);
}
fn writeTypeofPeer(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
@ -2780,9 +2768,8 @@ const Writer = struct {
}
fn writeClosureGet(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
const src = LazySrcLoc.nodeOffset(@bitCast(extended.operand));
try stream.print("{d})) ", .{extended.small});
try self.writeSrc(stream, src);
try self.writeSrcNode(stream, @bitCast(extended.operand));
}
fn writeInstRef(self: *Writer, stream: anytype, ref: Zir.Inst.Ref) !void {
@ -2858,30 +2845,44 @@ const Writer = struct {
try stream.writeAll(name);
}
fn writeSrc(self: *Writer, stream: anytype, src: LazySrcLoc) !void {
if (self.file.tree_loaded) {
const tree = self.file.tree;
const src_loc: Module.SrcLoc = .{
.file_scope = self.file,
.parent_decl_node = self.parent_decl_node,
.lazy = src,
};
const src_span = src_loc.span(self.gpa) catch unreachable;
const start = self.line_col_cursor.find(tree.source, src_span.start);
const end = self.line_col_cursor.find(tree.source, src_span.end);
try stream.print("{s}:{d}:{d} to :{d}:{d}", .{
@tagName(src), start.line + 1, start.column + 1,
end.line + 1, end.column + 1,
});
}
}
fn writeSrcNode(self: *Writer, stream: anytype, src_node: i32) !void {
return self.writeSrc(stream, LazySrcLoc.nodeOffset(src_node));
if (!self.file.tree_loaded) return;
const tree = self.file.tree;
const abs_node = self.relativeToNodeIndex(src_node);
const src_span = tree.nodeToSpan(abs_node);
const start = self.line_col_cursor.find(tree.source, src_span.start);
const end = self.line_col_cursor.find(tree.source, src_span.end);
try stream.print("node_offset:{d}:{d} to :{d}:{d}", .{
start.line + 1, start.column + 1,
end.line + 1, end.column + 1,
});
}
fn writeSrcTok(self: *Writer, stream: anytype, src_tok: u32) !void {
return self.writeSrc(stream, .{ .token_offset = src_tok });
if (!self.file.tree_loaded) return;
const tree = self.file.tree;
const abs_tok = tree.firstToken(self.parent_decl_node) + src_tok;
const span_start = tree.tokens.items(.start)[abs_tok];
const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(abs_tok).len));
const start = self.line_col_cursor.find(tree.source, span_start);
const end = self.line_col_cursor.find(tree.source, span_end);
try stream.print("token_offset:{d}:{d} to :{d}:{d}", .{
start.line + 1, start.column + 1,
end.line + 1, end.column + 1,
});
}
fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: u32) !void {
if (!self.file.tree_loaded) return;
const tree = self.file.tree;
const span_start = tree.tokens.items(.start)[src_tok];
const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len));
const start = self.line_col_cursor.find(tree.source, span_start);
const end = self.line_col_cursor.find(tree.source, span_end);
try stream.print("token_abs:{d}:{d} to :{d}:{d}", .{
start.line + 1, start.column + 1,
end.line + 1, end.column + 1,
});
}
fn writeBracedDecl(self: *Writer, stream: anytype, body: []const Zir.Inst.Index) !void {

View File

@ -3317,15 +3317,6 @@ pub const Type = struct {
}
}
pub fn declSrcLoc(ty: Type, mod: *Module) Module.SrcLoc {
return declSrcLocOrNull(ty, mod).?;
}
pub fn declSrcLocOrNull(ty: Type, mod: *Module) ?Module.SrcLoc {
const decl = ty.getOwnerDeclOrNull(mod) orelse return null;
return mod.declPtr(decl).srcLoc(mod);
}
pub fn getOwnerDecl(ty: Type, mod: *Module) InternPool.DeclIndex {
return ty.getOwnerDeclOrNull(mod) orelse unreachable;
}
@ -3341,6 +3332,37 @@ pub const Type = struct {
};
}
pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Module.LazySrcLoc {
const ip = &zcu.intern_pool;
return .{
.base_node_inst = switch (ip.indexToKey(ty.toIntern())) {
.struct_type => |info| switch (info) {
.declared => ip.loadStructType(ty.toIntern()).zir_index.unwrap() orelse return null,
else => return null,
},
.union_type => |info| switch (info) {
.declared => ip.loadUnionType(ty.toIntern()).zir_index,
else => return null,
},
.opaque_type => |info| switch (info) {
.declared => ip.loadOpaqueType(ty.toIntern()).zir_index,
else => return null,
},
.enum_type => |info| switch (info) {
.declared => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
.generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index, // must be declared since we can't generate tags when reifying
else => return null,
},
else => return null,
},
.offset = Module.LazySrcLoc.Offset.nodeOffset(0),
};
}
pub fn srcLoc(ty: Type, zcu: *Zcu) Module.LazySrcLoc {
return ty.srcLocOrNull(zcu).?;
}
pub fn isGenericPoison(ty: Type) bool {
return ty.toIntern() == .generic_poison_type;
}

View File

@ -18,4 +18,3 @@ pub export fn entry() void {
// target=native
//
// :7:28: error: no field named 'c' in enum 'meta.FieldEnum(tmp.MyStruct)'
// :?:?: note: enum declared here

View File

@ -15,4 +15,4 @@ export fn entry() void {
// target=native
//
// :6:9: error: enum tag value 60 already taken
// :4:5: note: other occurrence here
// :4:9: note: other occurrence here

View File

@ -6,4 +6,4 @@ export fn foo(comptime x: anytype, y: i32) i32 {
// backend=stage2
// target=native
//
// :1:27: error: comptime parameters not allowed in function with calling convention 'C'
// :1:15: error: comptime parameters not allowed in function with calling convention 'C'

View File

@ -7,4 +7,4 @@ export fn foo(num: anytype) i32 {
// backend=stage2
// target=native
//
// :1:20: error: generic parameters not allowed in function with calling convention 'C'
// :1:15: error: generic parameters not allowed in function with calling convention 'C'

View File

@ -19,5 +19,5 @@ comptime {
// target=native
//
// :5:30: error: comptime parameters not allowed in function with calling convention 'C'
// :6:41: error: generic parameters not allowed in function with calling convention 'C'
// :6:30: error: generic parameters not allowed in function with calling convention 'C'
// :1:15: error: comptime parameters not allowed in function with calling convention 'C'

View File

@ -27,9 +27,9 @@ export fn h() void {
// target=native
//
// :9:16: error: missing struct field: x
// :1:11: note: struct 'tmp.A' declared here
// :1:11: note: struct declared here
// :18:16: error: missing tuple field with index 1
// :16:11: note: struct declared here
// :22:16: error: missing tuple field with index 0
// :22:16: note: missing tuple field with index 1
// :16:11: note: struct 'tmp.B' declared here
// :16:11: note: struct declared here

View File

@ -14,5 +14,5 @@ comptime {
// target=native
//
// :5:17: error: missing struct field: b
// :1:11: note: struct 'tmp.S' declared here
// :1:11: note: struct declared here
// :9:15: note: called from here

View File

@ -31,5 +31,3 @@ export fn entry() void {
// target=native
//
// :13:16: error: enum fields missing in union
// :1:13: note: field 'arst' missing, declared here
// :1:13: note: enum declared here

View File

@ -31,4 +31,3 @@ export fn entry() void {
// target=native
//
// :12:16: error: no field named 'arst' in enum 'tmp.Tag'
// :1:13: note: enum declared here

View File

@ -27,4 +27,3 @@ export fn entry() void {
// target=native
//
// :9:16: error: no field named 'signed' in enum 'tmp.Tag'
// :1:13: note: enum declared here

View File

@ -27,6 +27,3 @@ export fn entry() void {
// target=native
//
// :12:16: error: enum fields missing in union
// :1:13: note: field 'signed' missing, declared here
// :1:13: note: field 'unsigned' missing, declared here
// :1:13: note: enum declared here

View File

@ -17,5 +17,5 @@ pub export fn entr2() void {
// backend=stage2
// target=native
//
// :4:9: error: range start value is greater than the end value
// :11:9: error: range start value is greater than the end value
// :4:10: error: range start value is greater than the end value
// :11:11: error: range start value is greater than the end value

View File

@ -14,5 +14,5 @@ export fn entry() void {
// backend=stage2
// target=native
//
// :6:5: error: enum tag value 60 already taken
// :4:5: note: other occurrence here
// :6:9: error: enum tag value 60 already taken
// :4:9: note: other occurrence here