Commit 1eaeb4a0a8
Changed files (34)
src
test
cases
compile_errors
src/arch/wasm/CodeGen.zig
@@ -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| {
src/arch/wasm/Emit.zig
@@ -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;
}
src/codegen/c.zig
@@ -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;
}
src/codegen/llvm.zig
@@ -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;
}
src/codegen/spirv.zig
@@ -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);
src/link/Elf/ZigObject.zig
@@ -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| {
src/link/MachO/ZigObject.zig
@@ -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(
src/link/Wasm/ZigObject.zig
@@ -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",
.{},
));
src/link/Coff.zig
@@ -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(
src/link/Plan9.zig
@@ -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(
src/Sema/comptime_ptr_access.zig
@@ -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);
src/Compilation.zig
@@ -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 },
};
},
src/crash_report.zig
@@ -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);
src/InternPool.zig
@@ -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,
src/Module.zig
@@ -107,8 +107,17 @@ intern_pool: InternPool = .{},
/// a Decl can have a failed_decls entry but have analysis status of success.
failed_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, *ErrorMsg) = .{},
/// Keep track of one `@compileLog` callsite per owner Decl.
-/// The value is the AST node index offset from the Decl.
-compile_log_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, i32) = .{},
+/// The value is the source location of the `@compileLog` call, convertible to a `LazySrcLoc`.
+compile_log_decls: std.AutoArrayHashMapUnmanaged(Decl.Index, extern struct {
+ base_node_inst: InternPool.TrackedInst.Index,
+ node_offset: i32,
+ pub fn src(self: @This()) LazySrcLoc {
+ return .{
+ .base_node_inst = self.base_node_inst,
+ .offset = LazySrcLoc.Offset.nodeOffset(self.node_offset),
+ };
+ }
+}) = .{},
/// Using a map here for consistency with the other fields here.
/// The ErrorMsg memory is owned by the `File`, using Module's general purpose allocator.
failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .{},
@@ -257,9 +266,6 @@ pub const Export = struct {
src: LazySrcLoc,
/// The Decl that performs the export. Note that this is *not* the Decl being exported.
owner_decl: Decl.Index,
- /// The Decl containing the export statement. Inline function calls
- /// may cause this to be different from the owner_decl.
- src_decl: Decl.Index,
exported: Exported,
status: enum {
in_progress,
@@ -278,12 +284,7 @@ pub const Export = struct {
};
pub fn getSrcLoc(exp: Export, mod: *Module) SrcLoc {
- const src_decl = mod.declPtr(exp.src_decl);
- return .{
- .file_scope = src_decl.getFileScope(mod),
- .parent_decl_node = src_decl.src_node,
- .lazy = exp.src,
- };
+ return exp.src.upgrade(mod);
}
};
@@ -343,9 +344,6 @@ pub const Decl = struct {
/// there is no parent.
src_namespace: Namespace.Index,
- /// The AST node index of this declaration.
- /// Must be recomputed when the corresponding source file is modified.
- src_node: Ast.Node.Index,
/// Line number corresponding to `src_node`. Stored separately so that source files
/// do not need to be loaded into memory in order to compute debug line numbers.
/// This value is absolute.
@@ -417,26 +415,6 @@ pub const Decl = struct {
return extra.data.getBodies(@intCast(extra.end), zir);
}
- pub fn relativeToNodeIndex(decl: Decl, offset: i32) Ast.Node.Index {
- return @bitCast(offset + @as(i32, @bitCast(decl.src_node)));
- }
-
- pub fn nodeIndexToRelative(decl: Decl, node_index: Ast.Node.Index) i32 {
- return @as(i32, @bitCast(node_index)) - @as(i32, @bitCast(decl.src_node));
- }
-
- pub fn srcLoc(decl: Decl, zcu: *Zcu) SrcLoc {
- return decl.nodeOffsetSrcLoc(0, zcu);
- }
-
- pub fn nodeOffsetSrcLoc(decl: Decl, node_offset: i32, zcu: *Zcu) SrcLoc {
- return .{
- .file_scope = decl.getFileScope(zcu),
- .parent_decl_node = decl.src_node,
- .lazy = LazySrcLoc.nodeOffset(node_offset),
- };
- }
-
pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
if (decl.name_fully_qualified) {
try writer.print("{}", .{decl.name.fmt(&zcu.intern_pool)});
@@ -551,101 +529,6 @@ pub const Decl = struct {
return decl.typeOf(zcu).abiAlignment(zcu);
}
- /// Upgrade a `LazySrcLoc` to a `SrcLoc` based on the `Decl` provided.
- pub fn toSrcLoc(decl: *Decl, lazy: LazySrcLoc, mod: *Module) SrcLoc {
- return switch (lazy) {
- .unneeded,
- .entire_file,
- .byte_abs,
- .token_abs,
- .node_abs,
- => .{
- .file_scope = decl.getFileScope(mod),
- .parent_decl_node = 0,
- .lazy = lazy,
- },
-
- .byte_offset,
- .token_offset,
- .node_offset,
- .node_offset_main_token,
- .node_offset_initializer,
- .node_offset_var_decl_ty,
- .node_offset_var_decl_align,
- .node_offset_var_decl_section,
- .node_offset_var_decl_addrspace,
- .node_offset_var_decl_init,
- .node_offset_builtin_call_arg0,
- .node_offset_builtin_call_arg1,
- .node_offset_builtin_call_arg2,
- .node_offset_builtin_call_arg3,
- .node_offset_builtin_call_arg4,
- .node_offset_builtin_call_arg5,
- .node_offset_ptrcast_operand,
- .node_offset_array_access_index,
- .node_offset_slice_ptr,
- .node_offset_slice_start,
- .node_offset_slice_end,
- .node_offset_slice_sentinel,
- .node_offset_call_func,
- .node_offset_field_name,
- .node_offset_field_name_init,
- .node_offset_deref_ptr,
- .node_offset_asm_source,
- .node_offset_asm_ret_ty,
- .node_offset_if_cond,
- .node_offset_bin_op,
- .node_offset_bin_lhs,
- .node_offset_bin_rhs,
- .node_offset_switch_operand,
- .node_offset_switch_special_prong,
- .node_offset_switch_range,
- .node_offset_switch_prong_capture,
- .node_offset_switch_prong_tag_capture,
- .node_offset_fn_type_align,
- .node_offset_fn_type_addrspace,
- .node_offset_fn_type_section,
- .node_offset_fn_type_cc,
- .node_offset_fn_type_ret_ty,
- .node_offset_param,
- .token_offset_param,
- .node_offset_anyframe_type,
- .node_offset_lib_name,
- .node_offset_array_type_len,
- .node_offset_array_type_sentinel,
- .node_offset_array_type_elem,
- .node_offset_un_op,
- .node_offset_ptr_elem,
- .node_offset_ptr_sentinel,
- .node_offset_ptr_align,
- .node_offset_ptr_addrspace,
- .node_offset_ptr_bitoffset,
- .node_offset_ptr_hostsize,
- .node_offset_container_tag,
- .node_offset_field_default,
- .node_offset_init_ty,
- .node_offset_store_ptr,
- .node_offset_store_operand,
- .node_offset_return_operand,
- .for_input,
- .for_capture_from_input,
- .array_cat_lhs,
- .array_cat_rhs,
- => .{
- .file_scope = decl.getFileScope(mod),
- .parent_decl_node = decl.src_node,
- .lazy = lazy,
- },
- inline .call_arg,
- .fn_proto_param,
- => |x| .{
- .file_scope = decl.getFileScope(mod),
- .parent_decl_node = mod.declPtr(x.decl).src_node,
- .lazy = lazy,
- },
- };
- }
-
pub fn declPtrType(decl: Decl, zcu: *Zcu) !Type {
assert(decl.has_tv);
const decl_ty = decl.typeOf(zcu);
@@ -661,6 +544,23 @@ pub const Decl = struct {
},
});
}
+
+ /// Returns the source location of this `Decl`.
+ /// Asserts that this `Decl` corresponds to what will in future be a `Nav` (Named
+ /// Addressable Value): a source-level declaration or generic instantiation.
+ pub fn navSrcLoc(decl: Decl, zcu: *Zcu) LazySrcLoc {
+ return .{
+ .base_node_inst = decl.zir_decl_index.unwrap() orelse inst: {
+ // generic instantiation
+ assert(decl.has_tv);
+ assert(decl.owns_tv);
+ const owner = zcu.funcInfo(decl.val.toIntern()).generic_owner;
+ const generic_owner_decl = zcu.declPtr(zcu.funcInfo(owner).owner_decl);
+ break :inst generic_owner_decl.zir_decl_index.unwrap().?;
+ },
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ };
+ }
};
/// This state is attached to every Decl when Module emit_h is non-null.
@@ -1137,18 +1037,17 @@ pub const ErrorMsg = struct {
/// Canonical reference to a position within a source file.
pub const SrcLoc = struct {
file_scope: *File,
- /// Might be 0 depending on tag of `lazy`.
- parent_decl_node: Ast.Node.Index,
- /// Relative to `parent_decl_node`.
- lazy: LazySrcLoc,
+ base_node: Ast.Node.Index,
+ /// Relative to `base_node`.
+ lazy: LazySrcLoc.Offset,
- pub fn declSrcToken(src_loc: SrcLoc) Ast.TokenIndex {
+ pub fn baseSrcToken(src_loc: SrcLoc) Ast.TokenIndex {
const tree = src_loc.file_scope.tree;
- return tree.firstToken(src_loc.parent_decl_node);
+ return tree.firstToken(src_loc.base_node);
}
- pub fn declRelativeToNodeIndex(src_loc: SrcLoc, offset: i32) Ast.Node.Index {
- return @bitCast(offset + @as(i32, @bitCast(src_loc.parent_decl_node)));
+ pub fn relativeToNodeIndex(src_loc: SrcLoc, offset: i32) Ast.Node.Index {
+ return @bitCast(offset + @as(i32, @bitCast(src_loc.base_node)));
}
pub const Span = Ast.Span;
@@ -1172,14 +1071,14 @@ pub const SrcLoc = struct {
},
.byte_offset => |byte_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const tok_index = src_loc.declSrcToken();
+ const tok_index = src_loc.baseSrcToken();
const start = tree.tokens.items(.start)[tok_index] + byte_off;
const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len));
return Span{ .start = start, .end = end, .main = start };
},
.token_offset => |tok_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const tok_index = src_loc.declSrcToken() + tok_off;
+ const tok_index = src_loc.baseSrcToken() + tok_off;
const start = tree.tokens.items(.start)[tok_index];
const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len));
return Span{ .start = start, .end = end, .main = start };
@@ -1187,25 +1086,25 @@ pub const SrcLoc = struct {
.node_offset => |traced_off| {
const node_off = traced_off.x;
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
assert(src_loc.file_scope.tree_loaded);
return tree.nodeToSpan(node);
},
.node_offset_main_token => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const main_token = tree.nodes.items(.main_token)[node];
return tree.tokensToSpan(main_token, main_token, main_token);
},
.node_offset_bin_op => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
assert(src_loc.file_scope.tree_loaded);
return tree.nodeToSpan(node);
},
.node_offset_initializer => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
return tree.tokensToSpan(
tree.firstToken(node) - 3,
tree.lastToken(node),
@@ -1214,7 +1113,7 @@ pub const SrcLoc = struct {
},
.node_offset_var_decl_ty => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const node_tags = tree.nodes.items(.tag);
const full = switch (node_tags[node]) {
.global_var_decl,
@@ -1238,41 +1137,51 @@ pub const SrcLoc = struct {
},
.node_offset_var_decl_align => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullVarDecl(node).?;
return tree.nodeToSpan(full.ast.align_node);
},
.node_offset_var_decl_section => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullVarDecl(node).?;
return tree.nodeToSpan(full.ast.section_node);
},
.node_offset_var_decl_addrspace => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullVarDecl(node).?;
return tree.nodeToSpan(full.ast.addrspace_node);
},
.node_offset_var_decl_init => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullVarDecl(node).?;
return tree.nodeToSpan(full.ast.init_node);
},
- .node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0),
- .node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1),
- .node_offset_builtin_call_arg2 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 2),
- .node_offset_builtin_call_arg3 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 3),
- .node_offset_builtin_call_arg4 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 4),
- .node_offset_builtin_call_arg5 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 5),
+ .node_offset_builtin_call_arg => |builtin_arg| {
+ const tree = try src_loc.file_scope.getTree(gpa);
+ const node_datas = tree.nodes.items(.data);
+ const node_tags = tree.nodes.items(.tag);
+ const node = src_loc.relativeToNodeIndex(builtin_arg.builtin_call_node);
+ const param = switch (node_tags[node]) {
+ .builtin_call_two, .builtin_call_two_comma => switch (builtin_arg.arg_index) {
+ 0 => node_datas[node].lhs,
+ 1 => node_datas[node].rhs,
+ else => unreachable,
+ },
+ .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + builtin_arg.arg_index],
+ else => unreachable,
+ };
+ return tree.nodeToSpan(param);
+ },
.node_offset_ptrcast_operand => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const main_tokens = tree.nodes.items(.main_token);
const node_datas = tree.nodes.items(.data);
const node_tags = tree.nodes.items(.tag);
- var node = src_loc.declRelativeToNodeIndex(node_off);
+ var node = src_loc.relativeToNodeIndex(node_off);
while (true) {
switch (node_tags[node]) {
.builtin_call_two, .builtin_call_two_comma => {},
@@ -1304,7 +1213,7 @@ pub const SrcLoc = struct {
.node_offset_array_access_index => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_datas = tree.nodes.items(.data);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
return tree.nodeToSpan(node_datas[node].rhs);
},
.node_offset_slice_ptr,
@@ -1313,7 +1222,7 @@ pub const SrcLoc = struct {
.node_offset_slice_sentinel,
=> |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullSlice(node).?;
const part_node = switch (src_loc.lazy) {
.node_offset_slice_ptr => full.ast.sliced,
@@ -1326,7 +1235,7 @@ pub const SrcLoc = struct {
},
.node_offset_call_func => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
var buf: [1]Ast.Node.Index = undefined;
const full = tree.fullCall(&buf, node).?;
return tree.nodeToSpan(full.ast.fn_expr);
@@ -1335,7 +1244,7 @@ pub const SrcLoc = struct {
const tree = try src_loc.file_scope.getTree(gpa);
const node_datas = tree.nodes.items(.data);
const node_tags = tree.nodes.items(.tag);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
var buf: [1]Ast.Node.Index = undefined;
const tok_index = switch (node_tags[node]) {
.field_access => node_datas[node].rhs,
@@ -1359,7 +1268,7 @@ pub const SrcLoc = struct {
},
.node_offset_field_name_init => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const tok_index = tree.firstToken(node) - 2;
const start = tree.tokens.items(.start)[tok_index];
const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len));
@@ -1367,18 +1276,18 @@ pub const SrcLoc = struct {
},
.node_offset_deref_ptr => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
return tree.nodeToSpan(node);
},
.node_offset_asm_source => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullAsm(node).?;
return tree.nodeToSpan(full.ast.template);
},
.node_offset_asm_ret_ty => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullAsm(node).?;
const asm_output = full.outputs[0];
const node_datas = tree.nodes.items(.data);
@@ -1387,7 +1296,7 @@ pub const SrcLoc = struct {
.node_offset_if_cond => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const node_tags = tree.nodes.items(.tag);
const src_node = switch (node_tags[node]) {
.if_simple,
@@ -1416,7 +1325,7 @@ pub const SrcLoc = struct {
},
.for_input => |for_input| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(for_input.for_node_offset);
+ const node = src_loc.relativeToNodeIndex(for_input.for_node_offset);
const for_full = tree.fullFor(node).?;
const src_node = for_full.ast.inputs[for_input.input_index];
return tree.nodeToSpan(src_node);
@@ -1424,7 +1333,7 @@ pub const SrcLoc = struct {
.for_capture_from_input => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const token_tags = tree.tokens.items(.tag);
- const input_node = src_loc.declRelativeToNodeIndex(node_off);
+ const input_node = src_loc.relativeToNodeIndex(node_off);
// We have to actually linear scan the whole AST to find the for loop
// that contains this input.
const node_tags = tree.nodes.items(.tag);
@@ -1465,7 +1374,7 @@ pub const SrcLoc = struct {
},
.call_arg => |call_arg| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(call_arg.call_node_offset);
+ const node = src_loc.relativeToNodeIndex(call_arg.call_node_offset);
var buf: [2]Ast.Node.Index = undefined;
const call_full = tree.fullCall(buf[0..1], node) orelse {
const node_tags = tree.nodes.items(.tag);
@@ -1501,43 +1410,49 @@ pub const SrcLoc = struct {
};
return tree.nodeToSpan(call_full.ast.params[call_arg.arg_index]);
},
- .fn_proto_param => |fn_proto_param| {
+ .fn_proto_param, .fn_proto_param_type => |fn_proto_param| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(fn_proto_param.fn_proto_node_offset);
+ const node = src_loc.relativeToNodeIndex(fn_proto_param.fn_proto_node_offset);
var buf: [1]Ast.Node.Index = undefined;
const full = tree.fullFnProto(&buf, node).?;
var it = full.iterate(tree);
var i: usize = 0;
while (it.next()) |param| : (i += 1) {
- if (i == fn_proto_param.param_index) {
- if (param.anytype_ellipsis3) |token| return tree.tokenToSpan(token);
- const first_token = param.comptime_noalias orelse
- param.name_token orelse
- tree.firstToken(param.type_expr);
- return tree.tokensToSpan(
- first_token,
- tree.lastToken(param.type_expr),
- first_token,
- );
+ if (i != fn_proto_param.param_index) continue;
+
+ switch (src_loc.lazy) {
+ .fn_proto_param_type => if (param.anytype_ellipsis3) |tok| {
+ return tree.tokenToSpan(tok);
+ } else {
+ return tree.nodeToSpan(param.type_expr);
+ },
+ .fn_proto_param => if (param.anytype_ellipsis3) |tok| {
+ const first = param.comptime_noalias orelse param.name_token orelse tok;
+ return tree.tokensToSpan(first, tok, first);
+ } else {
+ const first = param.comptime_noalias orelse param.name_token orelse tree.firstToken(param.type_expr);
+ return tree.tokensToSpan(first, tree.lastToken(param.type_expr), first);
+ },
+ else => unreachable,
}
}
unreachable;
},
.node_offset_bin_lhs => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const node_datas = tree.nodes.items(.data);
return tree.nodeToSpan(node_datas[node].lhs);
},
.node_offset_bin_rhs => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const node_datas = tree.nodes.items(.data);
return tree.nodeToSpan(node_datas[node].rhs);
},
.array_cat_lhs, .array_cat_rhs => |cat| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(cat.array_cat_offset);
+ const node = src_loc.relativeToNodeIndex(cat.array_cat_offset);
const node_datas = tree.nodes.items(.data);
const arr_node = if (src_loc.lazy == .array_cat_lhs)
node_datas[node].lhs
@@ -1565,14 +1480,14 @@ pub const SrcLoc = struct {
.node_offset_switch_operand => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const node_datas = tree.nodes.items(.data);
return tree.nodeToSpan(node_datas[node].lhs);
},
.node_offset_switch_special_prong => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const switch_node = src_loc.declRelativeToNodeIndex(node_off);
+ const switch_node = src_loc.relativeToNodeIndex(node_off);
const node_datas = tree.nodes.items(.data);
const node_tags = tree.nodes.items(.tag);
const main_tokens = tree.nodes.items(.main_token);
@@ -1592,7 +1507,7 @@ pub const SrcLoc = struct {
.node_offset_switch_range => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const switch_node = src_loc.declRelativeToNodeIndex(node_off);
+ const switch_node = src_loc.relativeToNodeIndex(node_off);
const node_datas = tree.nodes.items(.data);
const node_tags = tree.nodes.items(.tag);
const main_tokens = tree.nodes.items(.main_token);
@@ -1613,56 +1528,30 @@ pub const SrcLoc = struct {
}
} else unreachable;
},
- .node_offset_switch_prong_capture,
- .node_offset_switch_prong_tag_capture,
- => |node_off| {
- const tree = try src_loc.file_scope.getTree(gpa);
- const case_node = src_loc.declRelativeToNodeIndex(node_off);
- const case = tree.fullSwitchCase(case_node).?;
- const token_tags = tree.tokens.items(.tag);
- const start_tok = switch (src_loc.lazy) {
- .node_offset_switch_prong_capture => case.payload_token.?,
- .node_offset_switch_prong_tag_capture => blk: {
- var tok = case.payload_token.?;
- if (token_tags[tok] == .asterisk) tok += 1;
- tok += 2; // skip over comma
- break :blk tok;
- },
- else => unreachable,
- };
- const end_tok = switch (token_tags[start_tok]) {
- .asterisk => start_tok + 1,
- else => start_tok,
- };
- const start = tree.tokens.items(.start)[start_tok];
- const end_start = tree.tokens.items(.start)[end_tok];
- const end = end_start + @as(u32, @intCast(tree.tokenSlice(end_tok).len));
- return Span{ .start = start, .end = end, .main = start };
- },
.node_offset_fn_type_align => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
var buf: [1]Ast.Node.Index = undefined;
const full = tree.fullFnProto(&buf, node).?;
return tree.nodeToSpan(full.ast.align_expr);
},
.node_offset_fn_type_addrspace => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
var buf: [1]Ast.Node.Index = undefined;
const full = tree.fullFnProto(&buf, node).?;
return tree.nodeToSpan(full.ast.addrspace_expr);
},
.node_offset_fn_type_section => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
var buf: [1]Ast.Node.Index = undefined;
const full = tree.fullFnProto(&buf, node).?;
return tree.nodeToSpan(full.ast.section_expr);
},
.node_offset_fn_type_cc => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
var buf: [1]Ast.Node.Index = undefined;
const full = tree.fullFnProto(&buf, node).?;
return tree.nodeToSpan(full.ast.callconv_expr);
@@ -1670,7 +1559,7 @@ pub const SrcLoc = struct {
.node_offset_fn_type_ret_ty => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
var buf: [1]Ast.Node.Index = undefined;
const full = tree.fullFnProto(&buf, node).?;
return tree.nodeToSpan(full.ast.return_type);
@@ -1678,7 +1567,7 @@ pub const SrcLoc = struct {
.node_offset_param => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const token_tags = tree.tokens.items(.tag);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
var first_tok = tree.firstToken(node);
while (true) switch (token_tags[first_tok - 1]) {
@@ -1694,7 +1583,7 @@ pub const SrcLoc = struct {
.token_offset_param => |token_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const token_tags = tree.tokens.items(.tag);
- const main_token = tree.nodes.items(.main_token)[src_loc.parent_decl_node];
+ const main_token = tree.nodes.items(.main_token)[src_loc.base_node];
const tok_index = @as(Ast.TokenIndex, @bitCast(token_off + @as(i32, @bitCast(main_token))));
var first_tok = tok_index;
@@ -1712,13 +1601,13 @@ pub const SrcLoc = struct {
.node_offset_anyframe_type => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_datas = tree.nodes.items(.data);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
return tree.nodeToSpan(node_datas[parent_node].rhs);
},
.node_offset_lib_name => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
var buf: [1]Ast.Node.Index = undefined;
const full = tree.fullFnProto(&buf, parent_node).?;
const tok_index = full.lib_name.?;
@@ -1729,21 +1618,21 @@ pub const SrcLoc = struct {
.node_offset_array_type_len => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullArrayType(parent_node).?;
return tree.nodeToSpan(full.ast.elem_count);
},
.node_offset_array_type_sentinel => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullArrayType(parent_node).?;
return tree.nodeToSpan(full.ast.sentinel);
},
.node_offset_array_type_elem => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullArrayType(parent_node).?;
return tree.nodeToSpan(full.ast.elem_type);
@@ -1751,48 +1640,48 @@ pub const SrcLoc = struct {
.node_offset_un_op => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_datas = tree.nodes.items(.data);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
return tree.nodeToSpan(node_datas[node].lhs);
},
.node_offset_ptr_elem => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullPtrType(parent_node).?;
return tree.nodeToSpan(full.ast.child_type);
},
.node_offset_ptr_sentinel => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullPtrType(parent_node).?;
return tree.nodeToSpan(full.ast.sentinel);
},
.node_offset_ptr_align => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullPtrType(parent_node).?;
return tree.nodeToSpan(full.ast.align_node);
},
.node_offset_ptr_addrspace => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullPtrType(parent_node).?;
return tree.nodeToSpan(full.ast.addrspace_node);
},
.node_offset_ptr_bitoffset => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullPtrType(parent_node).?;
return tree.nodeToSpan(full.ast.bit_range_start);
},
.node_offset_ptr_hostsize => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full = tree.fullPtrType(parent_node).?;
return tree.nodeToSpan(full.ast.bit_range_end);
@@ -1800,7 +1689,7 @@ pub const SrcLoc = struct {
.node_offset_container_tag => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
switch (node_tags[parent_node]) {
.container_decl_arg, .container_decl_arg_trailing => {
@@ -1822,7 +1711,7 @@ pub const SrcLoc = struct {
.node_offset_field_default => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
const full: Ast.full.ContainerField = switch (node_tags[parent_node]) {
.container_field => tree.containerField(parent_node),
@@ -1833,7 +1722,7 @@ pub const SrcLoc = struct {
},
.node_offset_init_ty => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const parent_node = src_loc.declRelativeToNodeIndex(node_off);
+ const parent_node = src_loc.relativeToNodeIndex(node_off);
var buf: [2]Ast.Node.Index = undefined;
const type_expr = if (tree.fullArrayInit(&buf, parent_node)) |array_init|
@@ -1846,7 +1735,7 @@ pub const SrcLoc = struct {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
const node_datas = tree.nodes.items(.data);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
switch (node_tags[node]) {
.assign => {
@@ -1859,7 +1748,7 @@ pub const SrcLoc = struct {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
const node_datas = tree.nodes.items(.data);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
switch (node_tags[node]) {
.assign => {
@@ -1870,7 +1759,7 @@ pub const SrcLoc = struct {
},
.node_offset_return_operand => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
- const node = src_loc.declRelativeToNodeIndex(node_off);
+ const node = src_loc.relativeToNodeIndex(node_off);
const node_tags = tree.nodes.items(.tag);
const node_datas = tree.nodes.items(.data);
if (node_tags[node] == .@"return" and node_datas[node].lhs != 0) {
@@ -1878,381 +1767,629 @@ pub const SrcLoc = struct {
}
return tree.nodeToSpan(node);
},
- }
- }
+ .container_field_name,
+ .container_field_value,
+ .container_field_type,
+ .container_field_align,
+ => |field_idx| {
+ const tree = try src_loc.file_scope.getTree(gpa);
+ const node = src_loc.relativeToNodeIndex(0);
+ var buf: [2]Ast.Node.Index = undefined;
+ const container_decl = tree.fullContainerDecl(&buf, node) orelse
+ return tree.nodeToSpan(node);
+
+ var cur_field_idx: usize = 0;
+ for (container_decl.ast.members) |member_node| {
+ const field = tree.fullContainerField(member_node) orelse continue;
+ if (cur_field_idx < field_idx) {
+ cur_field_idx += 1;
+ continue;
+ }
+ const field_component_node = switch (src_loc.lazy) {
+ .container_field_name => 0,
+ .container_field_value => field.ast.value_expr,
+ .container_field_type => field.ast.type_expr,
+ .container_field_align => field.ast.align_expr,
+ else => unreachable,
+ };
+ if (field_component_node == 0) {
+ return tree.tokenToSpan(field.ast.main_token);
+ } else {
+ return tree.nodeToSpan(field_component_node);
+ }
+ } else unreachable;
+ },
+ .init_elem => |init_elem| {
+ const tree = try src_loc.file_scope.getTree(gpa);
+ const init_node = src_loc.relativeToNodeIndex(init_elem.init_node_offset);
+ var buf: [2]Ast.Node.Index = undefined;
+ if (tree.fullArrayInit(&buf, init_node)) |full| {
+ const elem_node = full.ast.elements[init_elem.elem_index];
+ return tree.nodeToSpan(elem_node);
+ } else if (tree.fullStructInit(&buf, init_node)) |full| {
+ const field_node = full.ast.fields[init_elem.elem_index];
+ return tree.tokensToSpan(
+ tree.firstToken(field_node) - 3,
+ tree.lastToken(field_node),
+ tree.nodes.items(.main_token)[field_node] - 2,
+ );
+ } else unreachable;
+ },
+ .init_field_name,
+ .init_field_linkage,
+ .init_field_section,
+ .init_field_visibility,
+ .init_field_rw,
+ .init_field_locality,
+ .init_field_cache,
+ .init_field_library,
+ .init_field_thread_local,
+ => |builtin_call_node| {
+ const wanted = switch (src_loc.lazy) {
+ .init_field_name => "name",
+ .init_field_linkage => "linkage",
+ .init_field_section => "section",
+ .init_field_visibility => "visibility",
+ .init_field_rw => "rw",
+ .init_field_locality => "locality",
+ .init_field_cache => "cache",
+ .init_field_library => "library",
+ .init_field_thread_local => "thread_local",
+ else => unreachable,
+ };
+ const tree = try src_loc.file_scope.getTree(gpa);
+ const node_datas = tree.nodes.items(.data);
+ const node_tags = tree.nodes.items(.tag);
+ const node = src_loc.relativeToNodeIndex(builtin_call_node);
+ const arg_node = switch (node_tags[node]) {
+ .builtin_call_two, .builtin_call_two_comma => node_datas[node].rhs,
+ .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + 1],
+ else => unreachable,
+ };
+ var buf: [2]Ast.Node.Index = undefined;
+ const full = tree.fullStructInit(&buf, arg_node) orelse
+ return tree.nodeToSpan(arg_node);
+ for (full.ast.fields) |field_node| {
+ // . IDENTIFIER = field_node
+ const name_token = tree.firstToken(field_node) - 2;
+ const name = tree.tokenSlice(name_token);
+ if (std.mem.eql(u8, name, wanted)) {
+ return tree.tokensToSpan(
+ name_token - 1,
+ tree.lastToken(field_node),
+ tree.nodes.items(.main_token)[field_node] - 2,
+ );
+ }
+ }
+ return tree.nodeToSpan(arg_node);
+ },
+ .switch_case_item,
+ .switch_case_item_range_first,
+ .switch_case_item_range_last,
+ .switch_capture,
+ .switch_tag_capture,
+ => {
+ const switch_node_offset, const want_case_idx = switch (src_loc.lazy) {
+ .switch_case_item,
+ .switch_case_item_range_first,
+ .switch_case_item_range_last,
+ => |x| .{ x.switch_node_offset, x.case_idx },
+ .switch_capture,
+ .switch_tag_capture,
+ => |x| .{ x.switch_node_offset, x.case_idx },
+ else => unreachable,
+ };
- pub fn byteOffsetBuiltinCallArg(
- src_loc: SrcLoc,
- gpa: Allocator,
- node_off: i32,
- arg_index: u32,
- ) !Span {
- const tree = try src_loc.file_scope.getTree(gpa);
- const node_datas = tree.nodes.items(.data);
- const node_tags = tree.nodes.items(.tag);
- const node = src_loc.declRelativeToNodeIndex(node_off);
- const param = switch (node_tags[node]) {
- .builtin_call_two, .builtin_call_two_comma => switch (arg_index) {
- 0 => node_datas[node].lhs,
- 1 => node_datas[node].rhs,
- else => unreachable,
+ const tree = try src_loc.file_scope.getTree(gpa);
+ const node_datas = tree.nodes.items(.data);
+ const node_tags = tree.nodes.items(.tag);
+ const main_tokens = tree.nodes.items(.main_token);
+ const switch_node = src_loc.relativeToNodeIndex(switch_node_offset);
+ const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
+ const case_nodes = tree.extra_data[extra.start..extra.end];
+
+ var multi_i: u32 = 0;
+ var scalar_i: u32 = 0;
+ const case = for (case_nodes) |case_node| {
+ const case = tree.fullSwitchCase(case_node).?;
+ const is_special = special: {
+ if (case.ast.values.len == 0) break :special true;
+ if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .identifier) {
+ break :special mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_");
+ }
+ break :special false;
+ };
+ if (is_special) {
+ if (want_case_idx.isSpecial()) {
+ break case;
+ }
+ }
+
+ const is_multi = case.ast.values.len != 1 or
+ node_tags[case.ast.values[0]] == .switch_range;
+
+ if (!want_case_idx.isSpecial()) switch (want_case_idx.kind) {
+ .scalar => if (!is_multi and want_case_idx.index == scalar_i) break case,
+ .multi => if (is_multi and want_case_idx.index == multi_i) break case,
+ };
+
+ if (is_multi) {
+ multi_i += 1;
+ } else {
+ scalar_i += 1;
+ }
+ } else unreachable;
+
+ const want_item = switch (src_loc.lazy) {
+ .switch_case_item,
+ .switch_case_item_range_first,
+ .switch_case_item_range_last,
+ => |x| x.item_idx,
+ .switch_capture, .switch_tag_capture => {
+ const token_tags = tree.tokens.items(.tag);
+ const start = switch (src_loc.lazy) {
+ .switch_capture => case.payload_token.?,
+ .switch_tag_capture => tok: {
+ var tok = case.payload_token.?;
+ if (token_tags[tok] == .asterisk) tok += 1;
+ tok += 2; // skip over comma
+ break :tok tok;
+ },
+ else => unreachable,
+ };
+ const end = switch (token_tags[start]) {
+ .asterisk => start + 1,
+ else => start,
+ };
+ return tree.tokensToSpan(start, end, start);
+ },
+ else => unreachable,
+ };
+
+ switch (want_item.kind) {
+ .single => {
+ var item_i: u32 = 0;
+ for (case.ast.values) |item_node| {
+ if (node_tags[item_node] == .switch_range) continue;
+ if (item_i != want_item.index) {
+ item_i += 1;
+ continue;
+ }
+ return tree.nodeToSpan(item_node);
+ } else unreachable;
+ },
+ .range => {
+ var range_i: u32 = 0;
+ for (case.ast.values) |item_node| {
+ if (node_tags[item_node] != .switch_range) continue;
+ if (range_i != want_item.index) {
+ range_i += 1;
+ continue;
+ }
+ return switch (src_loc.lazy) {
+ .switch_case_item => tree.nodeToSpan(item_node),
+ .switch_case_item_range_first => tree.nodeToSpan(node_datas[item_node].lhs),
+ .switch_case_item_range_last => tree.nodeToSpan(node_datas[item_node].rhs),
+ else => unreachable,
+ };
+ } else unreachable;
+ },
+ }
},
- .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + arg_index],
- else => unreachable,
- };
- return tree.nodeToSpan(param);
+ }
}
};
-/// Resolving a source location into a byte offset may require doing work
-/// that we would rather not do unless the error actually occurs.
-/// Therefore we need a data structure that contains the information necessary
-/// to lazily produce a `SrcLoc` as required.
-/// Most of the offsets in this data structure are relative to the containing Decl.
-/// This makes the source location resolve properly even when a Decl gets
-/// shifted up or down in the file, as long as the Decl's contents itself
-/// do not change.
-pub const LazySrcLoc = union(enum) {
- /// When this tag is set, the code that constructed this `LazySrcLoc` is asserting
- /// that all code paths which would need to resolve the source location are
- /// unreachable. If you are debugging this tag incorrectly being this value,
- /// look into using reverse-continue with a memory watchpoint to see where the
- /// value is being set to this tag.
- unneeded,
- /// Means the source location points to an entire file; not any particular
- /// location within the file. `file_scope` union field will be active.
- entire_file,
- /// The source location points to a byte offset within a source file,
- /// offset from 0. The source file is determined contextually.
- /// Inside a `SrcLoc`, the `file_scope` union field will be active.
- byte_abs: u32,
- /// The source location points to a token within a source file,
- /// offset from 0. The source file is determined contextually.
- /// Inside a `SrcLoc`, the `file_scope` union field will be active.
- token_abs: u32,
- /// The source location points to an AST node within a source file,
- /// offset from 0. The source file is determined contextually.
- /// Inside a `SrcLoc`, the `file_scope` union field will be active.
- node_abs: u32,
- /// The source location points to a byte offset within a source file,
- /// offset from the byte offset of the Decl within the file.
- /// The Decl is determined contextually.
- byte_offset: u32,
- /// This data is the offset into the token list from the Decl token.
- /// The Decl is determined contextually.
- token_offset: u32,
- /// The source location points to an AST node, which is this value offset
- /// from its containing Decl node AST index.
- /// The Decl is determined contextually.
- node_offset: TracedOffset,
- /// The source location points to the main token of an AST node, found
- /// by taking this AST node index offset from the containing Decl AST node.
- /// The Decl is determined contextually.
- node_offset_main_token: i32,
- /// The source location points to the beginning of a struct initializer.
- /// The Decl is determined contextually.
- node_offset_initializer: i32,
- /// The source location points to a variable declaration type expression,
- /// found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a variable declaration AST node. Next, navigate
- /// to the type expression.
- /// The Decl is determined contextually.
- node_offset_var_decl_ty: i32,
- /// The source location points to the alignment expression of a var decl.
- /// The Decl is determined contextually.
- node_offset_var_decl_align: i32,
- /// The source location points to the linksection expression of a var decl.
- /// The Decl is determined contextually.
- node_offset_var_decl_section: i32,
- /// The source location points to the addrspace expression of a var decl.
- /// The Decl is determined contextually.
- node_offset_var_decl_addrspace: i32,
- /// The source location points to the initializer of a var decl.
- /// The Decl is determined contextually.
- node_offset_var_decl_init: i32,
- /// The source location points to the first parameter of a builtin
- /// function call, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a builtin call AST node. Next, navigate
- /// to the first parameter.
- /// The Decl is determined contextually.
- node_offset_builtin_call_arg0: i32,
- /// Same as `node_offset_builtin_call_arg0` except arg index 1.
- node_offset_builtin_call_arg1: i32,
- node_offset_builtin_call_arg2: i32,
- node_offset_builtin_call_arg3: i32,
- node_offset_builtin_call_arg4: i32,
- node_offset_builtin_call_arg5: i32,
- /// Like `node_offset_builtin_call_arg0` but recurses through arbitrarily many calls
- /// to pointer cast builtins.
- node_offset_ptrcast_operand: i32,
- /// The source location points to the index expression of an array access
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to an array access AST node. Next, navigate
- /// to the index expression.
- /// The Decl is determined contextually.
- node_offset_array_access_index: i32,
- /// The source location points to the LHS of a slice expression
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a slice AST node. Next, navigate
- /// to the sentinel expression.
- /// The Decl is determined contextually.
- node_offset_slice_ptr: i32,
- /// The source location points to start expression of a slice expression
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a slice AST node. Next, navigate
- /// to the sentinel expression.
- /// The Decl is determined contextually.
- node_offset_slice_start: i32,
- /// The source location points to the end expression of a slice
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a slice AST node. Next, navigate
- /// to the sentinel expression.
- /// The Decl is determined contextually.
- node_offset_slice_end: i32,
- /// The source location points to the sentinel expression of a slice
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a slice AST node. Next, navigate
- /// to the sentinel expression.
- /// The Decl is determined contextually.
- node_offset_slice_sentinel: i32,
- /// The source location points to the callee expression of a function
- /// call expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a function call AST node. Next, navigate
- /// to the callee expression.
- /// The Decl is determined contextually.
- node_offset_call_func: i32,
- /// The payload is offset from the containing Decl AST node.
- /// The source location points to the field name of:
- /// * a field access expression (`a.b`), or
- /// * the callee of a method call (`a.b()`)
- /// The Decl is determined contextually.
- node_offset_field_name: i32,
- /// The payload is offset from the containing Decl AST node.
- /// The source location points to the field name of the operand ("b" node)
- /// of a field initialization expression (`.a = b`)
- /// The Decl is determined contextually.
- node_offset_field_name_init: i32,
- /// The source location points to the pointer of a pointer deref expression,
- /// found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a pointer deref AST node. Next, navigate
- /// to the pointer expression.
- /// The Decl is determined contextually.
- node_offset_deref_ptr: i32,
- /// The source location points to the assembly source code of an inline assembly
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to inline assembly AST node. Next, navigate
- /// to the asm template source code.
- /// The Decl is determined contextually.
- node_offset_asm_source: i32,
- /// The source location points to the return type of an inline assembly
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to inline assembly AST node. Next, navigate
- /// to the return type expression.
- /// The Decl is determined contextually.
- node_offset_asm_ret_ty: i32,
- /// The source location points to the condition expression of an if
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to an if expression AST node. Next, navigate
- /// to the condition expression.
- /// The Decl is determined contextually.
- node_offset_if_cond: i32,
- /// The source location points to a binary expression, such as `a + b`, found
- /// by taking this AST node index offset from the containing Decl AST node.
- /// The Decl is determined contextually.
- node_offset_bin_op: i32,
- /// The source location points to the LHS of a binary expression, found
- /// by taking this AST node index offset from the containing Decl AST node,
- /// which points to a binary expression AST node. Next, navigate to the LHS.
- /// The Decl is determined contextually.
- node_offset_bin_lhs: i32,
- /// The source location points to the RHS of a binary expression, found
- /// by taking this AST node index offset from the containing Decl AST node,
- /// which points to a binary expression AST node. Next, navigate to the RHS.
- /// The Decl is determined contextually.
- node_offset_bin_rhs: i32,
- /// The source location points to the operand of a switch expression, found
- /// by taking this AST node index offset from the containing Decl AST node,
- /// which points to a switch expression AST node. Next, navigate to the operand.
- /// The Decl is determined contextually.
- node_offset_switch_operand: i32,
- /// The source location points to the else/`_` prong of a switch expression, found
- /// by taking this AST node index offset from the containing Decl AST node,
- /// which points to a switch expression AST node. Next, navigate to the else/`_` prong.
- /// The Decl is determined contextually.
- node_offset_switch_special_prong: i32,
- /// The source location points to all the ranges of a switch expression, found
- /// by taking this AST node index offset from the containing Decl AST node,
- /// which points to a switch expression AST node. Next, navigate to any of the
- /// range nodes. The error applies to all of them.
- /// The Decl is determined contextually.
- node_offset_switch_range: i32,
- /// The source location points to the capture of a switch_prong.
- /// The Decl is determined contextually.
- node_offset_switch_prong_capture: i32,
- /// The source location points to the tag capture of a switch_prong.
- /// The Decl is determined contextually.
- node_offset_switch_prong_tag_capture: i32,
- /// The source location points to the align expr of a function type
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a function type AST node. Next, navigate to
- /// the calling convention node.
- /// The Decl is determined contextually.
- node_offset_fn_type_align: i32,
- /// The source location points to the addrspace expr of a function type
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a function type AST node. Next, navigate to
- /// the calling convention node.
- /// The Decl is determined contextually.
- node_offset_fn_type_addrspace: i32,
- /// The source location points to the linksection expr of a function type
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a function type AST node. Next, navigate to
- /// the calling convention node.
- /// The Decl is determined contextually.
- node_offset_fn_type_section: i32,
- /// The source location points to the calling convention of a function type
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a function type AST node. Next, navigate to
- /// the calling convention node.
- /// The Decl is determined contextually.
- node_offset_fn_type_cc: i32,
- /// The source location points to the return type of a function type
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a function type AST node. Next, navigate to
- /// the return type node.
- /// The Decl is determined contextually.
- node_offset_fn_type_ret_ty: i32,
- node_offset_param: i32,
- token_offset_param: i32,
- /// The source location points to the type expression of an `anyframe->T`
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to a `anyframe->T` expression AST node. Next, navigate
- /// to the type expression.
- /// The Decl is determined contextually.
- node_offset_anyframe_type: i32,
- /// The source location points to the string literal of `extern "foo"`, found
- /// by taking this AST node index offset from the containing
- /// Decl AST node, which points to a function prototype or variable declaration
- /// expression AST node. Next, navigate to the string literal of the `extern "foo"`.
- /// The Decl is determined contextually.
- node_offset_lib_name: i32,
- /// The source location points to the len expression of an `[N:S]T`
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to an `[N:S]T` expression AST node. Next, navigate
- /// to the len expression.
- /// The Decl is determined contextually.
- node_offset_array_type_len: i32,
- /// The source location points to the sentinel expression of an `[N:S]T`
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to an `[N:S]T` expression AST node. Next, navigate
- /// to the sentinel expression.
- /// The Decl is determined contextually.
- node_offset_array_type_sentinel: i32,
- /// The source location points to the elem expression of an `[N:S]T`
- /// expression, found by taking this AST node index offset from the containing
- /// Decl AST node, which points to an `[N:S]T` expression AST node. Next, navigate
- /// to the elem expression.
- /// The Decl is determined contextually.
- node_offset_array_type_elem: i32,
- /// The source location points to the operand of an unary expression.
- /// The Decl is determined contextually.
- node_offset_un_op: i32,
- /// The source location points to the elem type of a pointer.
- /// The Decl is determined contextually.
- node_offset_ptr_elem: i32,
- /// The source location points to the sentinel of a pointer.
- /// The Decl is determined contextually.
- node_offset_ptr_sentinel: i32,
- /// The source location points to the align expr of a pointer.
- /// The Decl is determined contextually.
- node_offset_ptr_align: i32,
- /// The source location points to the addrspace expr of a pointer.
- /// The Decl is determined contextually.
- node_offset_ptr_addrspace: i32,
- /// The source location points to the bit-offset of a pointer.
- /// The Decl is determined contextually.
- node_offset_ptr_bitoffset: i32,
- /// The source location points to the host size of a pointer.
- /// The Decl is determined contextually.
- node_offset_ptr_hostsize: i32,
- /// The source location points to the tag type of an union or an enum.
- /// The Decl is determined contextually.
- node_offset_container_tag: i32,
- /// The source location points to the default value of a field.
- /// The Decl is determined contextually.
- node_offset_field_default: i32,
- /// The source location points to the type of an array or struct initializer.
- /// The Decl is determined contextually.
- node_offset_init_ty: i32,
- /// The source location points to the LHS of an assignment.
- /// The Decl is determined contextually.
- node_offset_store_ptr: i32,
- /// The source location points to the RHS of an assignment.
- /// The Decl is determined contextually.
- node_offset_store_operand: i32,
- /// The source location points to the operand of a `return` statement, or
- /// the `return` itself if there is no explicit operand.
- /// The Decl is determined contextually.
- node_offset_return_operand: i32,
- /// The source location points to a for loop input.
- /// The Decl is determined contextually.
- for_input: struct {
- /// Points to the for loop AST node.
- for_node_offset: i32,
- /// Picks one of the inputs from the condition.
- input_index: u32,
- },
- /// The source location points to one of the captures of a for loop, found
- /// by taking this AST node index offset from the containing
- /// Decl AST node, which points to one of the input nodes of a for loop.
- /// Next, navigate to the corresponding capture.
- /// The Decl is determined contextually.
- for_capture_from_input: i32,
- /// The source location points to the argument node of a function call.
- call_arg: struct {
- decl: Decl.Index,
- /// Points to the function call AST node.
- call_node_offset: i32,
- /// The index of the argument the source location points to.
- arg_index: u32,
- },
- fn_proto_param: struct {
- decl: Decl.Index,
- /// Points to the function prototype AST node.
- fn_proto_node_offset: i32,
- /// The index of the parameter the source location points to.
- param_index: u32,
- },
- array_cat_lhs: ArrayCat,
- array_cat_rhs: ArrayCat,
-
- const ArrayCat = struct {
- /// Points to the array concat AST node.
- array_cat_offset: i32,
- /// The index of the element the source location points to.
- elem_index: u32,
- };
+pub const LazySrcLoc = struct {
+ /// This instruction provides the source node locations are resolved relative to.
+ /// It is a `declaration`, `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl`.
+ /// This must be valid even if `relative` is an absolute value, since it is required to
+ /// determine the file which the `LazySrcLoc` refers to.
+ base_node_inst: InternPool.TrackedInst.Index,
+ /// This field determines the source location relative to `base_node_inst`.
+ offset: Offset,
+
+ pub const Offset = union(enum) {
+ /// When this tag is set, the code that constructed this `LazySrcLoc` is asserting
+ /// that all code paths which would need to resolve the source location are
+ /// unreachable. If you are debugging this tag incorrectly being this value,
+ /// look into using reverse-continue with a memory watchpoint to see where the
+ /// value is being set to this tag.
+ /// `base_node_inst` is unused.
+ unneeded,
+ /// Means the source location points to an entire file; not any particular
+ /// location within the file. `file_scope` union field will be active.
+ entire_file,
+ /// The source location points to a byte offset within a source file,
+ /// offset from 0. The source file is determined contextually.
+ /// Inside a `SrcLoc`, the `file_scope` union field will be active.
+ byte_abs: u32,
+ /// The source location points to a token within a source file,
+ /// offset from 0. The source file is determined contextually.
+ /// Inside a `SrcLoc`, the `file_scope` union field will be active.
+ token_abs: u32,
+ /// The source location points to an AST node within a source file,
+ /// offset from 0. The source file is determined contextually.
+ /// Inside a `SrcLoc`, the `file_scope` union field will be active.
+ node_abs: u32,
+ /// The source location points to a byte offset within a source file,
+ /// offset from the byte offset of the base node within the file.
+ byte_offset: u32,
+ /// This data is the offset into the token list from the base node's first token.
+ token_offset: u32,
+ /// The source location points to an AST node, which is this value offset
+ /// from its containing base node AST index.
+ node_offset: TracedOffset,
+ /// The source location points to the main token of an AST node, found
+ /// by taking this AST node index offset from the containing base node.
+ node_offset_main_token: i32,
+ /// The source location points to the beginning of a struct initializer.
+ node_offset_initializer: i32,
+ /// The source location points to a variable declaration type expression,
+ /// found by taking this AST node index offset from the containing
+ /// base node, which points to a variable declaration AST node. Next, navigate
+ /// to the type expression.
+ node_offset_var_decl_ty: i32,
+ /// The source location points to the alignment expression of a var decl.
+ node_offset_var_decl_align: i32,
+ /// The source location points to the linksection expression of a var decl.
+ node_offset_var_decl_section: i32,
+ /// The source location points to the addrspace expression of a var decl.
+ node_offset_var_decl_addrspace: i32,
+ /// The source location points to the initializer of a var decl.
+ node_offset_var_decl_init: i32,
+ /// The source location points to the given argument of a builtin function call.
+ /// `builtin_call_node` points to the builtin call.
+ /// `arg_index` is the index of the argument which hte source location refers to.
+ node_offset_builtin_call_arg: struct {
+ builtin_call_node: i32,
+ arg_index: u32,
+ },
+ /// Like `node_offset_builtin_call_arg` but recurses through arbitrarily many calls
+ /// to pointer cast builtins (taking the first argument of the most nested).
+ node_offset_ptrcast_operand: i32,
+ /// The source location points to the index expression of an array access
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to an array access AST node. Next, navigate
+ /// to the index expression.
+ node_offset_array_access_index: i32,
+ /// The source location points to the LHS of a slice expression
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a slice AST node. Next, navigate
+ /// to the sentinel expression.
+ node_offset_slice_ptr: i32,
+ /// The source location points to start expression of a slice expression
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a slice AST node. Next, navigate
+ /// to the sentinel expression.
+ node_offset_slice_start: i32,
+ /// The source location points to the end expression of a slice
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a slice AST node. Next, navigate
+ /// to the sentinel expression.
+ node_offset_slice_end: i32,
+ /// The source location points to the sentinel expression of a slice
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a slice AST node. Next, navigate
+ /// to the sentinel expression.
+ node_offset_slice_sentinel: i32,
+ /// The source location points to the callee expression of a function
+ /// call expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a function call AST node. Next, navigate
+ /// to the callee expression.
+ node_offset_call_func: i32,
+ /// The payload is offset from the containing base node.
+ /// The source location points to the field name of:
+ /// * a field access expression (`a.b`), or
+ /// * the callee of a method call (`a.b()`)
+ node_offset_field_name: i32,
+ /// The payload is offset from the containing base node.
+ /// The source location points to the field name of the operand ("b" node)
+ /// of a field initialization expression (`.a = b`)
+ node_offset_field_name_init: i32,
+ /// The source location points to the pointer of a pointer deref expression,
+ /// found by taking this AST node index offset from the containing
+ /// base node, which points to a pointer deref AST node. Next, navigate
+ /// to the pointer expression.
+ node_offset_deref_ptr: i32,
+ /// The source location points to the assembly source code of an inline assembly
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to inline assembly AST node. Next, navigate
+ /// to the asm template source code.
+ node_offset_asm_source: i32,
+ /// The source location points to the return type of an inline assembly
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to inline assembly AST node. Next, navigate
+ /// to the return type expression.
+ node_offset_asm_ret_ty: i32,
+ /// The source location points to the condition expression of an if
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to an if expression AST node. Next, navigate
+ /// to the condition expression.
+ node_offset_if_cond: i32,
+ /// The source location points to a binary expression, such as `a + b`, found
+ /// by taking this AST node index offset from the containing base node.
+ node_offset_bin_op: i32,
+ /// The source location points to the LHS of a binary expression, found
+ /// by taking this AST node index offset from the containing base node,
+ /// which points to a binary expression AST node. Next, navigate to the LHS.
+ node_offset_bin_lhs: i32,
+ /// The source location points to the RHS of a binary expression, found
+ /// by taking this AST node index offset from the containing base node,
+ /// which points to a binary expression AST node. Next, navigate to the RHS.
+ node_offset_bin_rhs: i32,
+ /// The source location points to the operand of a switch expression, found
+ /// by taking this AST node index offset from the containing base node,
+ /// which points to a switch expression AST node. Next, navigate to the operand.
+ node_offset_switch_operand: i32,
+ /// The source location points to the else/`_` prong of a switch expression, found
+ /// by taking this AST node index offset from the containing base node,
+ /// which points to a switch expression AST node. Next, navigate to the else/`_` prong.
+ node_offset_switch_special_prong: i32,
+ /// The source location points to all the ranges of a switch expression, found
+ /// by taking this AST node index offset from the containing base node,
+ /// which points to a switch expression AST node. Next, navigate to any of the
+ /// range nodes. The error applies to all of them.
+ node_offset_switch_range: i32,
+ /// The source location points to the align expr of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a function type AST node. Next, navigate to
+ /// the calling convention node.
+ node_offset_fn_type_align: i32,
+ /// The source location points to the addrspace expr of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a function type AST node. Next, navigate to
+ /// the calling convention node.
+ node_offset_fn_type_addrspace: i32,
+ /// The source location points to the linksection expr of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a function type AST node. Next, navigate to
+ /// the calling convention node.
+ node_offset_fn_type_section: i32,
+ /// The source location points to the calling convention of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a function type AST node. Next, navigate to
+ /// the calling convention node.
+ node_offset_fn_type_cc: i32,
+ /// The source location points to the return type of a function type
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a function type AST node. Next, navigate to
+ /// the return type node.
+ node_offset_fn_type_ret_ty: i32,
+ node_offset_param: i32,
+ token_offset_param: i32,
+ /// The source location points to the type expression of an `anyframe->T`
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to a `anyframe->T` expression AST node. Next, navigate
+ /// to the type expression.
+ node_offset_anyframe_type: i32,
+ /// The source location points to the string literal of `extern "foo"`, found
+ /// by taking this AST node index offset from the containing
+ /// base node, which points to a function prototype or variable declaration
+ /// expression AST node. Next, navigate to the string literal of the `extern "foo"`.
+ node_offset_lib_name: i32,
+ /// The source location points to the len expression of an `[N:S]T`
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to an `[N:S]T` expression AST node. Next, navigate
+ /// to the len expression.
+ node_offset_array_type_len: i32,
+ /// The source location points to the sentinel expression of an `[N:S]T`
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to an `[N:S]T` expression AST node. Next, navigate
+ /// to the sentinel expression.
+ node_offset_array_type_sentinel: i32,
+ /// The source location points to the elem expression of an `[N:S]T`
+ /// expression, found by taking this AST node index offset from the containing
+ /// base node, which points to an `[N:S]T` expression AST node. Next, navigate
+ /// to the elem expression.
+ node_offset_array_type_elem: i32,
+ /// The source location points to the operand of an unary expression.
+ node_offset_un_op: i32,
+ /// The source location points to the elem type of a pointer.
+ node_offset_ptr_elem: i32,
+ /// The source location points to the sentinel of a pointer.
+ node_offset_ptr_sentinel: i32,
+ /// The source location points to the align expr of a pointer.
+ node_offset_ptr_align: i32,
+ /// The source location points to the addrspace expr of a pointer.
+ node_offset_ptr_addrspace: i32,
+ /// The source location points to the bit-offset of a pointer.
+ node_offset_ptr_bitoffset: i32,
+ /// The source location points to the host size of a pointer.
+ node_offset_ptr_hostsize: i32,
+ /// The source location points to the tag type of an union or an enum.
+ node_offset_container_tag: i32,
+ /// The source location points to the default value of a field.
+ node_offset_field_default: i32,
+ /// The source location points to the type of an array or struct initializer.
+ node_offset_init_ty: i32,
+ /// The source location points to the LHS of an assignment.
+ node_offset_store_ptr: i32,
+ /// The source location points to the RHS of an assignment.
+ node_offset_store_operand: i32,
+ /// The source location points to the operand of a `return` statement, or
+ /// the `return` itself if there is no explicit operand.
+ node_offset_return_operand: i32,
+ /// The source location points to a for loop input.
+ for_input: struct {
+ /// Points to the for loop AST node.
+ for_node_offset: i32,
+ /// Picks one of the inputs from the condition.
+ input_index: u32,
+ },
+ /// The source location points to one of the captures of a for loop, found
+ /// by taking this AST node index offset from the containing
+ /// base node, which points to one of the input nodes of a for loop.
+ /// Next, navigate to the corresponding capture.
+ for_capture_from_input: i32,
+ /// The source location points to the argument node of a function call.
+ call_arg: struct {
+ /// Points to the function call AST node.
+ call_node_offset: i32,
+ /// The index of the argument the source location points to.
+ arg_index: u32,
+ },
+ fn_proto_param: FnProtoParam,
+ fn_proto_param_type: FnProtoParam,
+ array_cat_lhs: ArrayCat,
+ array_cat_rhs: ArrayCat,
+ /// The source location points to the name of the field at the given index
+ /// of the container type declaration at the base node.
+ container_field_name: u32,
+ /// Like `continer_field_name`, but points at the field's default value.
+ container_field_value: u32,
+ /// Like `continer_field_name`, but points at the field's type.
+ container_field_type: u32,
+ /// Like `continer_field_name`, but points at the field's alignment.
+ container_field_align: u32,
+ /// The source location points to the given element/field of a struct or
+ /// array initialization expression.
+ init_elem: struct {
+ /// Points to the AST node of the initialization expression.
+ init_node_offset: i32,
+ /// The index of the field/element the source location points to.
+ elem_index: u32,
+ },
+ // The following source locations are like `init_elem`, but refer to a
+ // field with a specific name. If such a field is not given, the entire
+ // initialization expression is used instead.
+ // The `i32` points to the AST node of a builtin call, whose *second*
+ // argument is the init expression.
+ init_field_name: i32,
+ init_field_linkage: i32,
+ init_field_section: i32,
+ init_field_visibility: i32,
+ init_field_rw: i32,
+ init_field_locality: i32,
+ init_field_cache: i32,
+ init_field_library: i32,
+ init_field_thread_local: i32,
+ /// The source location points to the value of an item in a specific
+ /// case of a `switch`.
+ switch_case_item: SwitchItem,
+ /// The source location points to the "first" value of a range item in
+ /// a specific case of a `switch`.
+ switch_case_item_range_first: SwitchItem,
+ /// The source location points to the "last" value of a range item in
+ /// a specific case of a `switch`.
+ switch_case_item_range_last: SwitchItem,
+ /// The source location points to the main capture of a specific case of
+ /// a `switch`.
+ switch_capture: SwitchCapture,
+ /// The source location points to the "tag" capture (second capture) of
+ /// a specific case of a `switch`.
+ switch_tag_capture: SwitchCapture,
+
+ pub const FnProtoParam = struct {
+ /// The offset of the function prototype AST node.
+ fn_proto_node_offset: i32,
+ /// The index of the parameter the source location points to.
+ param_index: u32,
+ };
- pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
+ pub const SwitchItem = struct {
+ /// The offset of the switch AST node.
+ switch_node_offset: i32,
+ /// The index of the case to point to within this switch.
+ case_idx: SwitchCaseIndex,
+ /// The index of the item to point to within this case.
+ item_idx: SwitchItemIndex,
+ };
- noinline fn nodeOffsetDebug(node_offset: i32) LazySrcLoc {
- var result: LazySrcLoc = .{ .node_offset = .{ .x = node_offset } };
- result.node_offset.trace.addAddr(@returnAddress(), "init");
- return result;
- }
+ pub const SwitchCapture = struct {
+ /// The offset of the switch AST node.
+ switch_node_offset: i32,
+ /// The index of the case whose capture to point to.
+ case_idx: SwitchCaseIndex,
+ };
- fn nodeOffsetRelease(node_offset: i32) LazySrcLoc {
- return .{ .node_offset = .{ .x = node_offset } };
- }
+ pub const SwitchCaseIndex = packed struct(u32) {
+ kind: enum(u1) { scalar, multi },
+ index: u31,
- /// This wraps a simple integer in debug builds so that later on we can find out
- /// where in semantic analysis the value got set.
- pub const TracedOffset = struct {
- x: i32,
- trace: std.debug.Trace = std.debug.Trace.init,
+ pub const special: SwitchCaseIndex = @bitCast(@as(u32, std.math.maxInt(u32)));
+ pub fn isSpecial(idx: SwitchCaseIndex) bool {
+ return @as(u32, @bitCast(idx)) == @as(u32, @bitCast(special));
+ }
+ };
+
+ pub const SwitchItemIndex = packed struct(u32) {
+ kind: enum(u1) { single, range },
+ index: u31,
+ };
+
+ const ArrayCat = struct {
+ /// Points to the array concat AST node.
+ array_cat_offset: i32,
+ /// The index of the element the source location points to.
+ elem_index: u32,
+ };
+
+ pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
+
+ noinline fn nodeOffsetDebug(node_offset: i32) Offset {
+ var result: LazySrcLoc = .{ .node_offset = .{ .x = node_offset } };
+ result.node_offset.trace.addAddr(@returnAddress(), "init");
+ return result;
+ }
- const want_tracing = false;
+ fn nodeOffsetRelease(node_offset: i32) Offset {
+ return .{ .node_offset = .{ .x = node_offset } };
+ }
+
+ /// This wraps a simple integer in debug builds so that later on we can find out
+ /// where in semantic analysis the value got set.
+ pub const TracedOffset = struct {
+ x: i32,
+ trace: std.debug.Trace = std.debug.Trace.init,
+
+ const want_tracing = false;
+ };
};
+
+ pub const unneeded: LazySrcLoc = .{
+ .base_node_inst = undefined,
+ .offset = .unneeded,
+ };
+
+ pub fn resolveBaseNode(base_node_inst: InternPool.TrackedInst.Index, zcu: *Zcu) struct { *File, Ast.Node.Index } {
+ const want_path_digest, const zir_inst = inst: {
+ const info = base_node_inst.resolveFull(&zcu.intern_pool);
+ break :inst .{ info.path_digest, info.inst };
+ };
+ // TODO: avoid iterating all files for this!
+ const file = for (zcu.import_table.values()) |file| {
+ if (std.mem.eql(u8, &file.path_digest, &want_path_digest)) break file;
+ } else unreachable;
+ assert(file.zir_loaded);
+
+ const zir = file.zir;
+ const inst = zir.instructions.get(@intFromEnum(zir_inst));
+ const base_node: Ast.Node.Index = switch (inst.tag) {
+ .declaration => inst.data.declaration.src_node,
+ .extended => switch (inst.data.extended.opcode) {
+ .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_node,
+ .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,
+ .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_node,
+ .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_node,
+ else => unreachable,
+ },
+ else => unreachable,
+ };
+ return .{ file, base_node };
+ }
+
+ /// Resolve the file and AST node of `base_node_inst` to get a resolved `SrcLoc`.
+ /// TODO: it is incorrect to store a `SrcLoc` anywhere due to incremental compilation.
+ /// Probably the type should be removed entirely and this resolution performed on-the-fly when needed.
+ pub fn upgrade(lazy: LazySrcLoc, zcu: *Zcu) SrcLoc {
+ const file, const base_node = resolveBaseNode(lazy.base_node_inst, zcu);
+ return .{
+ .file_scope = file,
+ .base_node = base_node,
+ .lazy = lazy.offset,
+ };
+ }
};
pub const SemaError = error{ OutOfMemory, AnalysisFail };
@@ -2260,11 +2397,6 @@ pub const CompileError = error{
OutOfMemory,
/// When this is returned, the compile error for the failure has already been recorded.
AnalysisFail,
- /// Returned when a compile error needed to be reported but a provided LazySrcLoc was set
- /// to the `unneeded` tag. The source location was, in fact, needed. It is expected that
- /// somewhere up the call stack, the operation will be retried after doing expensive work
- /// to compute a source location.
- NeededSourceLocation,
/// A Type or Value was needed to be used during semantic analysis, but it was not available
/// because the function is generic. This is only seen when analyzing the body of a param
/// instruction.
@@ -3373,7 +3505,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
}
return error.AnalysisFail;
},
- error.NeededSourceLocation => unreachable,
error.GenericPoison => unreachable,
else => |e| {
decl.analysis = .sema_failure;
@@ -3381,7 +3512,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
try mod.retryable_failures.append(mod.gpa, InternPool.Depender.wrap(.{ .decl = decl_index }));
mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
mod.gpa,
- decl.srcLoc(mod),
+ decl.navSrcLoc(mod).upgrade(mod),
"unable to analyze: {s}",
.{@errorName(e)},
));
@@ -3555,7 +3686,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
decl_index,
try Module.ErrorMsg.create(
gpa,
- decl.srcLoc(zcu),
+ decl.navSrcLoc(zcu).upgrade(zcu),
"invalid liveness: {s}",
.{@errorName(err)},
),
@@ -3579,7 +3710,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
try zcu.failed_decls.ensureUnusedCapacity(gpa, 1);
zcu.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
gpa,
- decl.srcLoc(zcu),
+ decl.navSrcLoc(zcu).upgrade(zcu),
"unable to codegen: {s}",
.{@errorName(err)},
));
@@ -3814,7 +3945,7 @@ fn semaFile(mod: *Module, file: *File) SemaError!void {
});
errdefer mod.destroyNamespace(new_namespace_index);
- const new_decl_index = try mod.allocateNewDecl(new_namespace_index, 0);
+ const new_decl_index = try mod.allocateNewDecl(new_namespace_index);
const new_decl = mod.declPtr(new_decl_index);
errdefer @panic("TODO error handling");
@@ -3961,7 +4092,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
var analysis_arena = std.heap.ArenaAllocator.init(gpa);
defer analysis_arena.deinit();
- var comptime_err_ret_trace = std.ArrayList(SrcLoc).init(gpa);
+ var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
defer comptime_err_ret_trace.deinit();
var sema: Sema = .{
@@ -3996,6 +4127,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = decl.zir_decl_index.unwrap().?,
};
defer block_scope.instructions.deinit(gpa);
@@ -4005,11 +4137,11 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
// We'll do some other bits with the Sema. Clear the type target index just
// in case they analyze any type.
sema.builtin_type_target_index = .none;
- const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = 0 };
- const section_src: LazySrcLoc = .{ .node_offset_var_decl_section = 0 };
- const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 };
- const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 };
- const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 };
+ const align_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_align = 0 });
+ const section_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_section = 0 });
+ const address_space_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_addrspace = 0 });
+ const ty_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_ty = 0 });
+ const init_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_init = 0 });
const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref);
const decl_ty = decl_val.typeOf(mod);
@@ -4143,7 +4275,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
}
if (decl.is_exported) {
- const export_src: LazySrcLoc = .{ .token_offset = @intFromBool(decl.is_pub) };
+ const export_src: LazySrcLoc = block_scope.src(.{ .token_offset = @intFromBool(decl.is_pub) });
if (is_inline) return sema.fail(&block_scope, export_src, "export of inline function", .{});
// The scope needs to have the decl in it.
try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index);
@@ -4697,14 +4829,13 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
const was_exported = decl.is_exported;
assert(decl.kind == kind); // ZIR tracking should preserve this
decl.name = decl_name;
- decl.src_node = inst_data.src_node;
decl.src_line = line;
decl.is_pub = declaration.flags.is_pub;
decl.is_exported = declaration.flags.is_export;
break :decl_index .{ was_exported, decl_index };
} else decl_index: {
// Create and set up a new Decl.
- const new_decl_index = try zcu.allocateNewDecl(namespace_index, inst_data.src_node);
+ const new_decl_index = try zcu.allocateNewDecl(namespace_index);
const new_decl = zcu.declPtr(new_decl_index);
new_decl.kind = kind;
new_decl.name = decl_name;
@@ -4858,7 +4989,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index }));
- var comptime_err_ret_trace = std.ArrayList(SrcLoc).init(gpa);
+ var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
defer comptime_err_ret_trace.deinit();
// In the case of a generic function instance, this is the type of the
@@ -4913,6 +5044,14 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
.instructions = .{},
.inlining = null,
.is_comptime = false,
+ .src_base_inst = inst: {
+ const owner_info = if (func.generic_owner == .none)
+ func
+ else
+ mod.funcInfo(func.generic_owner);
+ const orig_decl = mod.declPtr(owner_info.owner_decl);
+ break :inst orig_decl.zir_decl_index.unwrap().?;
+ },
};
defer inner_block.instructions.deinit(gpa);
@@ -4954,7 +5093,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
runtime_param_index += 1;
const opt_opv = sema.typeHasOnePossibleValue(Type.fromInterned(param_ty)) catch |err| switch (err) {
- error.NeededSourceLocation => unreachable,
error.GenericPoison => unreachable,
error.ComptimeReturn => unreachable,
error.ComptimeBreak => unreachable,
@@ -4988,7 +5126,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
// TODO make these unreachable instead of @panic
- error.NeededSourceLocation => @panic("zig compiler bug: NeededSourceLocation"),
error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
else => |e| return e,
@@ -5010,7 +5147,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
{
sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
// TODO make these unreachable instead of @panic
- error.NeededSourceLocation => @panic("zig compiler bug: NeededSourceLocation"),
error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
error.ComptimeReturn => @panic("zig compiler bug: ComptimeReturn"),
error.ComptimeBreak => @panic("zig compiler bug: ComptimeBreak"),
@@ -5031,8 +5167,10 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
// state to success, so that "unable to resolve inferred error set" errors
// can be emitted here.
if (sema.fn_ret_ty_ies) |ies| {
- sema.resolveInferredErrorSetPtr(&inner_block, LazySrcLoc.nodeOffset(0), ies) catch |err| switch (err) {
- error.NeededSourceLocation => unreachable,
+ sema.resolveInferredErrorSetPtr(&inner_block, .{
+ .base_node_inst = inner_block.src_base_inst,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ }, ies) catch |err| switch (err) {
error.GenericPoison => unreachable,
error.ComptimeReturn => unreachable,
error.ComptimeBreak => unreachable,
@@ -5056,7 +5194,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
// so that dependencies on the function body will now be satisfied rather than
// result in circular dependency errors.
sema.resolveFnTypes(fn_ty) catch |err| switch (err) {
- error.NeededSourceLocation => unreachable,
error.GenericPoison => unreachable,
error.ComptimeReturn => unreachable,
error.ComptimeBreak => unreachable,
@@ -5073,7 +5210,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
// the backends.
for (sema.types_to_resolve.keys()) |ty| {
sema.resolveTypeFully(Type.fromInterned(ty)) catch |err| switch (err) {
- error.NeededSourceLocation => unreachable,
error.GenericPoison => unreachable,
error.ComptimeReturn => unreachable,
error.ComptimeBreak => unreachable,
@@ -5101,17 +5237,11 @@ pub fn destroyNamespace(mod: *Module, index: Namespace.Index) void {
return mod.intern_pool.destroyNamespace(mod.gpa, index);
}
-pub fn allocateNewDecl(
- mod: *Module,
- namespace: Namespace.Index,
- src_node: Ast.Node.Index,
-) !Decl.Index {
- const ip = &mod.intern_pool;
- const gpa = mod.gpa;
- const decl_index = try ip.createDecl(gpa, .{
+pub fn allocateNewDecl(zcu: *Zcu, namespace: Namespace.Index) !Decl.Index {
+ const gpa = zcu.gpa;
+ const decl_index = try zcu.intern_pool.createDecl(gpa, .{
.name = undefined,
.src_namespace = namespace,
- .src_node = src_node,
.src_line = undefined,
.has_tv = false,
.owns_tv = false,
@@ -5126,10 +5256,10 @@ pub fn allocateNewDecl(
.kind = .anon,
});
- if (mod.emit_h) |mod_emit_h| {
- if (@intFromEnum(decl_index) >= mod_emit_h.allocated_emit_h.len) {
- try mod_emit_h.allocated_emit_h.append(gpa, .{});
- assert(@intFromEnum(decl_index) == mod_emit_h.allocated_emit_h.len);
+ if (zcu.emit_h) |zcu_emit_h| {
+ if (@intFromEnum(decl_index) >= zcu_emit_h.allocated_emit_h.len) {
+ try zcu_emit_h.allocated_emit_h.append(gpa, .{});
+ assert(@intFromEnum(decl_index) == zcu_emit_h.allocated_emit_h.len);
}
}
@@ -5223,376 +5353,6 @@ fn lockAndClearFileCompileError(mod: *Module, file: *File) void {
}
}
-pub const SwitchProngSrc = union(enum) {
- /// The item for a scalar prong.
- scalar: u32,
- /// A given single item for a multi prong.
- multi: Multi,
- /// A given range item for a multi prong.
- range: Multi,
- /// The item for the special prong.
- special,
- /// The main capture for a scalar prong.
- scalar_capture: u32,
- /// The main capture for a multi prong.
- multi_capture: u32,
- /// The main capture for the special prong.
- special_capture,
- /// The tag capture for a scalar prong.
- scalar_tag_capture: u32,
- /// The tag capture for a multi prong.
- multi_tag_capture: u32,
- /// The tag capture for the special prong.
- special_tag_capture,
-
- pub const Multi = struct {
- prong: u32,
- item: u32,
- };
-
- pub const RangeExpand = enum { none, first, last };
-
- /// This function is intended to be called only when it is certain that we need
- /// the LazySrcLoc in order to emit a compile error.
- pub fn resolve(
- prong_src: SwitchProngSrc,
- mod: *Module,
- decl: *Decl,
- switch_node_offset: i32,
- /// Ignored if `prong_src` is not `.range`
- range_expand: RangeExpand,
- ) LazySrcLoc {
- @setCold(true);
- const gpa = mod.gpa;
- const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
- // In this case we emit a warning + a less precise source location.
- log.warn("unable to load {s}: {s}", .{
- decl.getFileScope(mod).sub_file_path, @errorName(err),
- });
- return LazySrcLoc.nodeOffset(0);
- };
- const switch_node = decl.relativeToNodeIndex(switch_node_offset);
- const main_tokens = tree.nodes.items(.main_token);
- const node_datas = tree.nodes.items(.data);
- const node_tags = tree.nodes.items(.tag);
- const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
- const case_nodes = tree.extra_data[extra.start..extra.end];
-
- var multi_i: u32 = 0;
- var scalar_i: u32 = 0;
- const case_node = for (case_nodes) |case_node| {
- const case = tree.fullSwitchCase(case_node).?;
-
- const is_special = special: {
- if (case.ast.values.len == 0) break :special true;
- if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .identifier) {
- break :special mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_");
- }
- break :special false;
- };
-
- if (is_special) {
- switch (prong_src) {
- .special, .special_capture, .special_tag_capture => break case_node,
- else => continue,
- }
- }
-
- const is_multi = case.ast.values.len != 1 or
- node_tags[case.ast.values[0]] == .switch_range;
-
- switch (prong_src) {
- .scalar,
- .scalar_capture,
- .scalar_tag_capture,
- => |i| if (!is_multi and i == scalar_i) break case_node,
-
- .multi_capture,
- .multi_tag_capture,
- => |i| if (is_multi and i == multi_i) break case_node,
-
- .multi,
- .range,
- => |m| if (is_multi and m.prong == multi_i) break case_node,
-
- .special,
- .special_capture,
- .special_tag_capture,
- => {},
- }
-
- if (is_multi) {
- multi_i += 1;
- } else {
- scalar_i += 1;
- }
- } else unreachable;
-
- const case = tree.fullSwitchCase(case_node).?;
-
- switch (prong_src) {
- .scalar, .special => return LazySrcLoc.nodeOffset(
- decl.nodeIndexToRelative(case.ast.values[0]),
- ),
- .multi => |m| {
- var item_i: u32 = 0;
- for (case.ast.values) |item_node| {
- if (node_tags[item_node] == .switch_range) continue;
- if (item_i == m.item) return LazySrcLoc.nodeOffset(
- decl.nodeIndexToRelative(item_node),
- );
- item_i += 1;
- }
- unreachable;
- },
- .range => |m| {
- var range_i: u32 = 0;
- for (case.ast.values) |range| {
- if (node_tags[range] != .switch_range) continue;
- if (range_i == m.item) switch (range_expand) {
- .none => return LazySrcLoc.nodeOffset(
- decl.nodeIndexToRelative(range),
- ),
- .first => return LazySrcLoc.nodeOffset(
- decl.nodeIndexToRelative(node_datas[range].lhs),
- ),
- .last => return LazySrcLoc.nodeOffset(
- decl.nodeIndexToRelative(node_datas[range].rhs),
- ),
- };
- range_i += 1;
- }
- unreachable;
- },
- .scalar_capture, .multi_capture, .special_capture => {
- return .{ .node_offset_switch_prong_capture = decl.nodeIndexToRelative(case_node) };
- },
- .scalar_tag_capture, .multi_tag_capture, .special_tag_capture => {
- return .{ .node_offset_switch_prong_tag_capture = decl.nodeIndexToRelative(case_node) };
- },
- }
- }
-};
-
-pub const PeerTypeCandidateSrc = union(enum) {
- /// Do not print out error notes for candidate sources
- none: void,
- /// When we want to know the the src of candidate i, look up at
- /// index i in this slice
- override: []const ?LazySrcLoc,
- /// resolvePeerTypes originates from a @TypeOf(...) call
- typeof_builtin_call_node_offset: i32,
-
- pub fn resolve(
- self: PeerTypeCandidateSrc,
- mod: *Module,
- decl: *Decl,
- candidate_i: usize,
- ) ?LazySrcLoc {
- @setCold(true);
- const gpa = mod.gpa;
-
- switch (self) {
- .none => {
- return null;
- },
- .override => |candidate_srcs| {
- if (candidate_i >= candidate_srcs.len)
- return null;
- return candidate_srcs[candidate_i];
- },
- .typeof_builtin_call_node_offset => |node_offset| {
- switch (candidate_i) {
- 0 => return LazySrcLoc{ .node_offset_builtin_call_arg0 = node_offset },
- 1 => return LazySrcLoc{ .node_offset_builtin_call_arg1 = node_offset },
- 2 => return LazySrcLoc{ .node_offset_builtin_call_arg2 = node_offset },
- 3 => return LazySrcLoc{ .node_offset_builtin_call_arg3 = node_offset },
- 4 => return LazySrcLoc{ .node_offset_builtin_call_arg4 = node_offset },
- 5 => return LazySrcLoc{ .node_offset_builtin_call_arg5 = node_offset },
- else => {},
- }
-
- const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
- // In this case we emit a warning + a less precise source location.
- log.warn("unable to load {s}: {s}", .{
- decl.getFileScope(mod).sub_file_path, @errorName(err),
- });
- return LazySrcLoc.nodeOffset(0);
- };
- const node = decl.relativeToNodeIndex(node_offset);
- const node_datas = tree.nodes.items(.data);
- const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
-
- return LazySrcLoc{ .node_abs = params[candidate_i] };
- },
- }
- }
-};
-
-const FieldSrcQuery = struct {
- index: usize,
- range: enum { name, type, value, alignment } = .name,
-};
-
-fn queryFieldSrc(
- tree: Ast,
- query: FieldSrcQuery,
- file_scope: *File,
- container_decl: Ast.full.ContainerDecl,
-) SrcLoc {
- var field_index: usize = 0;
- for (container_decl.ast.members) |member_node| {
- const field = tree.fullContainerField(member_node) orelse continue;
- if (field_index == query.index) {
- return switch (query.range) {
- .name => .{
- .file_scope = file_scope,
- .parent_decl_node = 0,
- .lazy = .{ .token_abs = field.ast.main_token },
- },
- .type => .{
- .file_scope = file_scope,
- .parent_decl_node = 0,
- .lazy = .{ .node_abs = field.ast.type_expr },
- },
- .value => .{
- .file_scope = file_scope,
- .parent_decl_node = 0,
- .lazy = .{ .node_abs = field.ast.value_expr },
- },
- .alignment => .{
- .file_scope = file_scope,
- .parent_decl_node = 0,
- .lazy = .{ .node_abs = field.ast.align_expr },
- },
- };
- }
- field_index += 1;
- }
- unreachable;
-}
-
-pub fn paramSrc(
- func_node_offset: i32,
- mod: *Module,
- decl: *Decl,
- param_i: usize,
-) LazySrcLoc {
- @setCold(true);
- const gpa = mod.gpa;
- const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
- // In this case we emit a warning + a less precise source location.
- log.warn("unable to load {s}: {s}", .{
- decl.getFileScope(mod).sub_file_path, @errorName(err),
- });
- return LazySrcLoc.nodeOffset(0);
- };
- const node = decl.relativeToNodeIndex(func_node_offset);
- var buf: [1]Ast.Node.Index = undefined;
- const full = tree.fullFnProto(&buf, node).?;
- var it = full.iterate(tree);
- var i: usize = 0;
- while (it.next()) |param| : (i += 1) {
- if (i == param_i) {
- if (param.anytype_ellipsis3) |some| {
- const main_token = tree.nodes.items(.main_token)[decl.src_node];
- return .{ .token_offset_param = @as(i32, @bitCast(some)) - @as(i32, @bitCast(main_token)) };
- }
- return .{ .node_offset_param = decl.nodeIndexToRelative(param.type_expr) };
- }
- }
- unreachable;
-}
-
-pub fn initSrc(
- mod: *Module,
- init_node_offset: i32,
- decl: *Decl,
- init_index: usize,
-) LazySrcLoc {
- @setCold(true);
- const gpa = mod.gpa;
- const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
- // In this case we emit a warning + a less precise source location.
- log.warn("unable to load {s}: {s}", .{
- decl.getFileScope(mod).sub_file_path, @errorName(err),
- });
- return LazySrcLoc.nodeOffset(0);
- };
- const node_tags = tree.nodes.items(.tag);
- const node = decl.relativeToNodeIndex(init_node_offset);
- var buf: [2]Ast.Node.Index = undefined;
- switch (node_tags[node]) {
- .array_init_one,
- .array_init_one_comma,
- .array_init_dot_two,
- .array_init_dot_two_comma,
- .array_init_dot,
- .array_init_dot_comma,
- .array_init,
- .array_init_comma,
- => {
- const full = tree.fullArrayInit(&buf, node).?.ast.elements;
- return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(full[init_index]));
- },
- .struct_init_one,
- .struct_init_one_comma,
- .struct_init_dot_two,
- .struct_init_dot_two_comma,
- .struct_init_dot,
- .struct_init_dot_comma,
- .struct_init,
- .struct_init_comma,
- => {
- const full = tree.fullStructInit(&buf, node).?.ast.fields;
- return LazySrcLoc{ .node_offset_initializer = decl.nodeIndexToRelative(full[init_index]) };
- },
- else => return LazySrcLoc.nodeOffset(init_node_offset),
- }
-}
-
-pub fn optionsSrc(mod: *Module, decl: *Decl, base_src: LazySrcLoc, wanted: []const u8) LazySrcLoc {
- @setCold(true);
- const gpa = mod.gpa;
- const tree = decl.getFileScope(mod).getTree(gpa) catch |err| {
- // In this case we emit a warning + a less precise source location.
- log.warn("unable to load {s}: {s}", .{
- decl.getFileScope(mod).sub_file_path, @errorName(err),
- });
- return LazySrcLoc.nodeOffset(0);
- };
-
- const o_i: struct { off: i32, i: u8 } = switch (base_src) {
- .node_offset_builtin_call_arg0 => |n| .{ .off = n, .i = 0 },
- .node_offset_builtin_call_arg1 => |n| .{ .off = n, .i = 1 },
- else => unreachable,
- };
-
- const node = decl.relativeToNodeIndex(o_i.off);
- const node_datas = tree.nodes.items(.data);
- const node_tags = tree.nodes.items(.tag);
- const arg_node = switch (node_tags[node]) {
- .builtin_call_two, .builtin_call_two_comma => switch (o_i.i) {
- 0 => node_datas[node].lhs,
- 1 => node_datas[node].rhs,
- else => unreachable,
- },
- .builtin_call, .builtin_call_comma => tree.extra_data[node_datas[node].lhs + o_i.i],
- else => unreachable,
- };
- var buf: [2]std.zig.Ast.Node.Index = undefined;
- const init_nodes = if (tree.fullStructInit(&buf, arg_node)) |struct_init| struct_init.ast.fields else return base_src;
- for (init_nodes) |init_node| {
- // . IDENTIFIER = init_node
- const name_token = tree.firstToken(init_node) - 2;
- const name = tree.tokenSlice(name_token);
- if (std.mem.eql(u8, name, wanted)) {
- return LazySrcLoc{ .node_offset_initializer = decl.nodeIndexToRelative(init_node) };
- }
- }
- return base_src;
-}
-
/// Called from `Compilation.update`, after everything is done, just before
/// reporting compile errors. In this function we emit exported symbol collision
/// errors and communicate exported symbols to the linker backend.
@@ -5826,7 +5586,7 @@ pub fn linkerUpdateDecl(zcu: *Zcu, decl_index: Decl.Index) !void {
try zcu.failed_decls.ensureUnusedCapacity(gpa, 1);
zcu.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
gpa,
- decl.srcLoc(zcu),
+ decl.navSrcLoc(zcu).upgrade(zcu),
"unable to codegen: {s}",
.{@errorName(err)},
));
@@ -5857,7 +5617,7 @@ fn reportRetryableFileError(
mod.gpa,
.{
.file_scope = file,
- .parent_decl_node = 0,
+ .base_node = 0,
.lazy = .entire_file,
},
format,
@@ -6432,27 +6192,6 @@ pub fn funcInfo(mod: *Module, func_index: InternPool.Index) InternPool.Key.Func
return mod.intern_pool.indexToKey(func_index).func;
}
-pub fn fieldSrcLoc(mod: *Module, owner_decl_index: Decl.Index, query: FieldSrcQuery) SrcLoc {
- @setCold(true);
- const owner_decl = mod.declPtr(owner_decl_index);
- const file = owner_decl.getFileScope(mod);
- const tree = file.getTree(mod.gpa) catch |err| {
- // In this case we emit a warning + a less precise source location.
- log.warn("unable to load {s}: {s}", .{
- file.sub_file_path, @errorName(err),
- });
- return owner_decl.srcLoc(mod);
- };
- const node = owner_decl.relativeToNodeIndex(0);
- var buf: [2]Ast.Node.Index = undefined;
- if (tree.fullContainerDecl(&buf, node)) |container_decl| {
- return queryFieldSrc(tree.*, query, file, container_decl);
- } else {
- // This type was generated using @Type
- return owner_decl.srcLoc(mod);
- }
-}
-
pub fn toEnum(mod: *Module, comptime E: type, val: Value) E {
return mod.intern_pool.toEnum(E, val.toIntern());
}
src/print_value.zig
@@ -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,
};
}
src/print_zir.zig
@@ -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 {
src/RangeSet.zig
@@ -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;
src/Sema.zig
@@ -34,7 +34,7 @@ func_index: InternPool.Index,
func_is_naked: bool,
/// Used to restore the error return trace when returning a non-error from a function.
error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none,
-comptime_err_ret_trace: *std.ArrayList(Module.SrcLoc),
+comptime_err_ret_trace: *std.ArrayList(LazySrcLoc),
/// When semantic analysis needs to know the return type of the function whose body
/// is being analyzed, this `Type` should be used instead of going through `func`.
/// This will correctly handle the case of a comptime/inline function call of a
@@ -65,9 +65,7 @@ generic_owner: InternPool.Index = .none,
/// instantiation callsite so that compile errors on the parameter types of the
/// instantiation can point back to the instantiation site in addition to the
/// declaration site.
-generic_call_src: LazySrcLoc = .unneeded,
-/// Corresponds to `generic_call_src`.
-generic_call_decl: InternPool.OptionalDeclIndex = .none,
+generic_call_src: LazySrcLoc = LazySrcLoc.unneeded,
/// The key is types that must be fully resolved prior to machine code
/// generation pass. Types are added to this set when resolving them
/// immediately could cause a dependency loop, but they do need to be resolved
@@ -131,7 +129,6 @@ const MaybeComptimeAlloc = struct {
/// If the instruction is one of these three tags, `src` may be `.unneeded`.
stores: std.MultiArrayList(struct {
inst: Air.Inst.Index,
- src_decl: InternPool.DeclIndex,
src: LazySrcLoc,
}) = .{},
};
@@ -361,8 +358,8 @@ pub const Block = struct {
label: ?*Label = null,
inlining: ?*Inlining,
/// If runtime_index is not 0 then one of these is guaranteed to be non null.
- runtime_cond: ?Module.SrcLoc = null,
- runtime_loop: ?Module.SrcLoc = null,
+ runtime_cond: ?LazySrcLoc = null,
+ runtime_loop: ?LazySrcLoc = null,
/// This Decl is the Decl according to the Zig source code corresponding to this Block.
/// This can vary during inline or comptime function calls. See `Sema.owner_decl`
/// for the one that will be the same for all Block instances.
@@ -395,25 +392,39 @@ pub const Block = struct {
/// `block` in order for codegen to match lexical scoping for debug vars.
need_debug_scope: ?*bool = null,
- // These functions will be less stupid soon!
+ /// Relative source locations encountered while traversing this block should be
+ /// treated as relative to the AST node of this ZIR instruction.
+ src_base_inst: InternPool.TrackedInst.Index,
+
+ /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.
+ /// Specifically, the given `Offset` is treated as relative to `block.src_base_inst`.
+ pub fn src(block: Block, offset: LazySrcLoc.Offset) LazySrcLoc {
+ return .{
+ .base_node_inst = block.src_base_inst,
+ .offset = offset,
+ };
+ }
+
+ fn builtinCallArgSrc(block: *Block, builtin_call_node: i32, arg_index: u32) LazySrcLoc {
+ return block.src(.{ .node_offset_builtin_call_arg = .{
+ .builtin_call_node = builtin_call_node,
+ .arg_index = arg_index,
+ } });
+ }
fn nodeOffset(block: Block, node_offset: i32) LazySrcLoc {
- _ = block;
- return LazySrcLoc.nodeOffset(node_offset);
+ return block.src(LazySrcLoc.Offset.nodeOffset(node_offset));
}
fn tokenOffset(block: Block, tok_offset: u32) LazySrcLoc {
- _ = block;
- return .{ .token_offset = tok_offset };
+ return block.src(.{ .token_offset = tok_offset });
}
const ComptimeReason = union(enum) {
c_import: struct {
- block: *Block,
src: LazySrcLoc,
},
comptime_ret_ty: struct {
- block: *Block,
func: Air.Inst.Ref,
func_src: LazySrcLoc,
return_ty: Type,
@@ -425,27 +436,23 @@ pub const Block = struct {
const prefix = "expression is evaluated at comptime because ";
switch (cr) {
.c_import => |ci| {
- try sema.errNote(ci.block, ci.src, parent, prefix ++ "it is inside a @cImport", .{});
+ try sema.errNote(ci.src, parent, prefix ++ "it is inside a @cImport", .{});
},
.comptime_ret_ty => |rt| {
- const src_loc = if (try sema.funcDeclSrc(rt.func)) |fn_decl| blk: {
- var src_loc = fn_decl.srcLoc(mod);
- src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 };
- break :blk src_loc;
- } else blk: {
- const src_decl = mod.declPtr(rt.block.src_decl);
- break :blk src_decl.toSrcLoc(rt.func_src, mod);
- };
+ const ret_ty_src: LazySrcLoc = if (try sema.funcDeclSrc(rt.func)) |fn_decl| .{
+ .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
+ .offset = .{ .node_offset_fn_type_ret_ty = 0 },
+ } else rt.func_src;
if (rt.return_ty.isGenericPoison()) {
- return mod.errNoteNonLazy(src_loc, parent, prefix ++ "the generic function was instantiated with a comptime-only return type", .{});
+ return sema.errNote(ret_ty_src, parent, prefix ++ "the generic function was instantiated with a comptime-only return type", .{});
}
- try mod.errNoteNonLazy(
- src_loc,
+ try sema.errNote(
+ ret_ty_src,
parent,
prefix ++ "the function returns a comptime-only type '{}'",
.{rt.return_ty.fmt(mod)},
);
- try sema.explainWhyTypeIsComptime(parent, src_loc, rt.return_ty);
+ try sema.explainWhyTypeIsComptime(parent, ret_ty_src, rt.return_ty);
},
}
}
@@ -525,6 +532,7 @@ pub const Block = struct {
.c_import_buf = parent.c_import_buf,
.error_return_trace_index = parent.error_return_trace_index,
.need_debug_scope = parent.need_debug_scope,
+ .src_base_inst = parent.src_base_inst,
};
}
@@ -815,14 +823,6 @@ pub const Block = struct {
return result_index;
}
- fn addUnreachable(block: *Block, src: LazySrcLoc, safety_check: bool) !void {
- if (safety_check and block.wantSafety()) {
- try block.sema.safetyPanic(block, src, .unreach);
- } else {
- _ = try block.addNoOp(.unreach);
- }
- }
-
pub fn ownerModule(block: Block) *Package.Module {
const zcu = block.sema.mod;
return zcu.namespacePtr(block.namespace).file_scope.mod;
@@ -1237,7 +1237,7 @@ fn analyzeBodyInner(
.@"asm" => try sema.zirAsm( block, extended, false),
.asm_expr => try sema.zirAsm( block, extended, true),
.typeof_peer => try sema.zirTypeofPeer( block, extended, inst),
- .compile_log => try sema.zirCompileLog( extended),
+ .compile_log => try sema.zirCompileLog( block, extended),
.min_multi => try sema.zirMinMaxMulti( block, extended, .min),
.max_multi => try sema.zirMinMaxMulti( block, extended, .max),
.add_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode),
@@ -1475,10 +1475,9 @@ fn analyzeBodyInner(
if (@intFromEnum(target_runtime_index) < @intFromEnum(block.runtime_index)) {
const runtime_src = block.runtime_cond orelse block.runtime_loop.?;
const msg = msg: {
- const msg = try sema.errMsg(block, src, "comptime control flow inside runtime block", .{});
+ const msg = try sema.errMsg(src, "comptime control flow inside runtime block", .{});
errdefer msg.destroy(sema.gpa);
-
- try mod.errNoteNonLazy(runtime_src, msg, "runtime control flow here", .{});
+ try sema.errNote(runtime_src, msg, "runtime control flow here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -1522,7 +1521,7 @@ fn analyzeBodyInner(
.repeat => {
if (block.is_comptime) {
// Send comptime control flow back to the beginning of this block.
- const src = LazySrcLoc.nodeOffset(datas[@intFromEnum(inst)].node);
+ const src = block.nodeOffset(datas[@intFromEnum(inst)].node);
try sema.emitBackwardBranch(block, src);
i = 0;
continue;
@@ -1535,7 +1534,7 @@ fn analyzeBodyInner(
},
.repeat_inline => {
// Send comptime control flow back to the beginning of this block.
- const src = LazySrcLoc.nodeOffset(datas[@intFromEnum(inst)].node);
+ const src = block.nodeOffset(datas[@intFromEnum(inst)].node);
try sema.emitBackwardBranch(block, src);
i = 0;
continue;
@@ -1705,7 +1704,7 @@ fn analyzeBodyInner(
}
// Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/8220
const inst_data = datas[@intFromEnum(inst)].pl_node;
- const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
+ const cond_src = block.src(.{ .node_offset_if_cond = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
const then_body = sema.code.bodySlice(extra.end, extra.data.then_body_len);
const else_body = sema.code.bodySlice(
@@ -1725,7 +1724,7 @@ fn analyzeBodyInner(
},
.condbr_inline => blk: {
const inst_data = datas[@intFromEnum(inst)].pl_node;
- const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
+ const cond_src = block.src(.{ .node_offset_if_cond = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
const then_body = sema.code.bodySlice(extra.end, extra.data.then_body_len);
const else_body = sema.code.bodySlice(
@@ -1749,7 +1748,7 @@ fn analyzeBodyInner(
if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
+ const operand_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
const err_union = try sema.resolveInst(extra.data.operand);
@@ -1775,7 +1774,7 @@ fn analyzeBodyInner(
if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst);
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
+ const operand_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
const operand = try sema.resolveInst(extra.data.operand);
@@ -1939,14 +1938,14 @@ fn resolveDestType(
// Cast builtins use their result type as the destination type, but
// it could be an anytype argument, which we can't catch in AstGen.
const msg = msg: {
- const msg = try sema.errMsg(block, src, "{s} must have a known result type", .{builtin_name});
+ const msg = try sema.errMsg(src, "{s} must have a known result type", .{builtin_name});
errdefer msg.destroy(sema.gpa);
switch (sema.genericPoisonReason(block, zir_ref)) {
- .anytype_param => |call_src| try sema.errNote(block, call_src, msg, "result type is unknown due to anytype parameter", .{}),
- .anyopaque_ptr => |ptr_src| try sema.errNote(block, ptr_src, msg, "result type is unknown due to opaque pointer type", .{}),
+ .anytype_param => |call_src| try sema.errNote(call_src, msg, "result type is unknown due to anytype parameter", .{}),
+ .anyopaque_ptr => |ptr_src| try sema.errNote(ptr_src, msg, "result type is unknown due to opaque pointer type", .{}),
.unknown => {},
}
- try sema.errNote(block, src, msg, "use @as to provide explicit result type", .{});
+ try sema.errNote(src, msg, "use @as to provide explicit result type", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -2051,7 +2050,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
var err_trace_block = block.makeSubBlock();
defer err_trace_block.instructions.deinit(gpa);
- const src: LazySrcLoc = .unneeded;
+ const src: LazySrcLoc = LazySrcLoc.unneeded;
// var addrs: [err_return_trace_addr_count]usize = undefined;
const err_return_trace_addr_count = 32;
@@ -2212,9 +2211,9 @@ pub fn resolveFinalDeclValue(
fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc, reason: NeededComptimeReason) CompileError {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "unable to resolve comptime value", .{});
+ const msg = try sema.errMsg(src, "unable to resolve comptime value", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "{s}", .{reason.needed_comptime_reason});
+ try sema.errNote(src, msg, "{s}", .{reason.needed_comptime_reason});
if (reason.block_comptime_reason) |block_comptime_reason| {
try block_comptime_reason.explain(sema, msg);
@@ -2241,12 +2240,12 @@ fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: T
fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non_optional_ty: Type) CompileError {
const mod = sema.mod;
const msg = msg: {
- const msg = try sema.errMsg(block, src, "expected optional type, found '{}'", .{
+ const msg = try sema.errMsg(src, "expected optional type, found '{}'", .{
non_optional_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
if (non_optional_ty.zigTypeTag(mod) == .ErrorUnion) {
- try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{});
+ try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
}
try addDeclaredHereNote(sema, msg, non_optional_ty);
break :msg msg;
@@ -2257,12 +2256,12 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non
fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
const mod = sema.mod;
const msg = msg: {
- const msg = try sema.errMsg(block, src, "type '{}' does not support array initialization syntax", .{
+ const msg = try sema.errMsg(src, "type '{}' does not support array initialization syntax", .{
ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
if (ty.isSlice(mod)) {
- try sema.errNote(block, src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(mod).fmt(mod)});
+ try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2(mod).fmt(mod)});
}
break :msg msg;
};
@@ -2291,11 +2290,11 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
const zcu = sema.mod;
if (int_ty.zigTypeTag(zcu) == .Vector) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "overflow of vector type '{}' with value '{}'", .{
+ const msg = try sema.errMsg(src, "overflow of vector type '{}' with value '{}'", .{
int_ty.fmt(zcu), val.fmtValue(zcu, sema),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "when computing vector element at index '{d}'", .{vector_index});
+ try sema.errNote(src, msg, "when computing vector element at index '{d}'", .{vector_index});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -2308,15 +2307,14 @@ fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty:
fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazySrcLoc, container_ty: Type, field_index: usize) CompileError {
const mod = sema.mod;
const msg = msg: {
- const msg = try sema.errMsg(block, init_src, "value stored in comptime field does not match the default value of the field", .{});
+ const msg = try sema.errMsg(init_src, "value stored in comptime field does not match the default value of the field", .{});
errdefer msg.destroy(sema.gpa);
const struct_type = mod.typeToStruct(container_ty) orelse break :msg msg;
- const default_value_src = mod.fieldSrcLoc(struct_type.decl.unwrap().?, .{
- .index = field_index,
- .range = .value,
- });
- try mod.errNoteNonLazy(default_value_src, msg, "default value set here", .{});
+ try sema.errNote(.{
+ .base_node_inst = struct_type.zir_index.unwrap().?,
+ .offset = .{ .container_field_value = @intCast(field_index) },
+ }, msg, "default value set here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -2324,7 +2322,7 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "async has not been implemented in the self-hosted compiler yet", .{});
+ const msg = try sema.errMsg(src, "async has not been implemented in the self-hosted compiler yet", .{});
errdefer msg.destroy(sema.gpa);
break :msg msg;
};
@@ -2345,9 +2343,9 @@ fn failWithInvalidFieldAccess(
const child_ty = inner_ty.optionalChild(mod);
if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :opt;
const msg = msg: {
- const msg = try sema.errMsg(block, src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "consider using '.?', 'orelse', or 'if'", .{});
+ try sema.errNote(src, msg, "consider using '.?', 'orelse', or 'if'", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -2355,9 +2353,9 @@ fn failWithInvalidFieldAccess(
const child_ty = inner_ty.errorUnionPayload(mod);
if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :err;
const msg = msg: {
- const msg = try sema.errMsg(block, src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(src, "error union type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{});
+ try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -2390,11 +2388,11 @@ fn failWithComptimeErrorRetTrace(
) CompileError {
const mod = sema.mod;
const msg = msg: {
- const msg = try sema.errMsg(block, src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)});
+ const msg = try sema.errMsg(src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)});
errdefer msg.destroy(sema.gpa);
for (sema.comptime_err_ret_trace.items) |src_loc| {
- try mod.errNoteNonLazy(src_loc, msg, "error returned here", .{});
+ try sema.errNote(src_loc, msg, "error returned here", .{});
}
break :msg msg;
};
@@ -2403,17 +2401,15 @@ fn failWithComptimeErrorRetTrace(
/// We don't return a pointer to the new error note because the pointer
/// becomes invalid when you add another one.
-fn errNote(
+pub fn errNote(
sema: *Sema,
- block: *Block,
src: LazySrcLoc,
parent: *Module.ErrorMsg,
comptime format: []const u8,
args: anytype,
) error{OutOfMemory}!void {
- const mod = sema.mod;
- const src_decl = mod.declPtr(block.src_decl);
- return mod.errNoteNonLazy(src_decl.toSrcLoc(src, mod), parent, format, args);
+ const zcu = sema.mod;
+ return zcu.errNoteNonLazy(src.upgrade(zcu), parent, format, args);
}
fn addFieldErrNote(
@@ -2425,52 +2421,23 @@ fn addFieldErrNote(
args: anytype,
) !void {
@setCold(true);
- const mod = sema.mod;
- const decl_index = container_ty.getOwnerDecl(mod);
- const decl = mod.declPtr(decl_index);
-
- const field_src = blk: {
- const tree = decl.getFileScope(mod).getTree(sema.gpa) catch |err| {
- log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});
- break :blk decl.srcLoc(mod);
- };
-
- const container_node = decl.relativeToNodeIndex(0);
- const node_tags = tree.nodes.items(.tag);
- var buf: [2]std.zig.Ast.Node.Index = undefined;
- const container_decl = tree.fullContainerDecl(&buf, container_node) orelse break :blk decl.srcLoc(mod);
-
- var it_index: usize = 0;
- for (container_decl.ast.members) |member_node| {
- switch (node_tags[member_node]) {
- .container_field_init,
- .container_field_align,
- .container_field,
- => {
- if (it_index == field_index) {
- break :blk decl.nodeOffsetSrcLoc(decl.nodeIndexToRelative(member_node), mod);
- }
- it_index += 1;
- },
- else => continue,
- }
- }
- unreachable;
+ const zcu = sema.mod;
+ const type_src = container_ty.srcLocOrNull(zcu) orelse return;
+ const field_src: LazySrcLoc = .{
+ .base_node_inst = type_src.base_node_inst,
+ .offset = .{ .container_field_name = @intCast(field_index) },
};
- try mod.errNoteNonLazy(field_src, parent, format, args);
+ try sema.errNote(field_src, parent, format, args);
}
pub fn errMsg(
sema: *Sema,
- block: *Block,
src: LazySrcLoc,
comptime format: []const u8,
args: anytype,
-) error{ NeededSourceLocation, OutOfMemory }!*Module.ErrorMsg {
- const mod = sema.mod;
- if (src == .unneeded) return error.NeededSourceLocation;
- const src_decl = mod.declPtr(block.src_decl);
- return Module.ErrorMsg.create(sema.gpa, src_decl.toSrcLoc(src, mod), format, args);
+) Allocator.Error!*Module.ErrorMsg {
+ assert(src.offset != .unneeded);
+ return Module.ErrorMsg.create(sema.gpa, src.upgrade(sema.mod), format, args);
}
pub fn fail(
@@ -2480,7 +2447,7 @@ pub fn fail(
comptime format: []const u8,
args: anytype,
) CompileError {
- const err_msg = try sema.errMsg(block, src, format, args);
+ const err_msg = try sema.errMsg(src, format, args);
inline for (args) |arg| {
if (@TypeOf(arg) == Type.Formatter) {
try addDeclaredHereNote(sema, err_msg, arg.data.ty);
@@ -2514,7 +2481,6 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
var block_it = start_block;
while (block_it.inlining) |inlining| {
try sema.errNote(
- inlining.call_block,
inlining.call_src,
err_msg,
"called from here",
@@ -2548,7 +2514,7 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
const decl = mod.declPtr(ref.referencer);
try reference_stack.append(.{
.decl = decl.name,
- .src_loc = decl.toSrcLoc(ref.src, mod),
+ .src_loc = ref.src.upgrade(mod),
});
}
referenced_by = ref.referencer;
@@ -2583,15 +2549,13 @@ pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Module.Error
/// Reference trace is preserved.
fn reparentOwnedErrorMsg(
sema: *Sema,
- block: *Block,
src: LazySrcLoc,
msg: *Module.ErrorMsg,
comptime format: []const u8,
args: anytype,
) !void {
const mod = sema.mod;
- const src_decl = mod.declPtr(block.src_decl);
- const resolved_src = src_decl.toSrcLoc(src, mod);
+ const resolved_src = src.upgrade(mod);
const msg_str = try std.fmt.allocPrint(mod.gpa, format, args);
const orig_notes = msg.notes.len;
@@ -2728,7 +2692,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
sema.code.nullTerminatedString(str),
.no_embedded_nulls,
);
- const decl = try sema.lookupIdentifier(block, .unneeded, decl_name); // TODO: could we need this src loc?
+ const decl = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?
break :capture InternPool.CaptureValue.wrap(.{ .decl_val = decl });
},
.decl_ref => |str| capture: {
@@ -2737,7 +2701,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
sema.code.nullTerminatedString(str),
.no_embedded_nulls,
);
- const decl = try sema.lookupIdentifier(block, .unneeded, decl_name); // TODO: could we need this src loc?
+ const decl = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?
break :capture InternPool.CaptureValue.wrap(.{ .decl_ref = decl });
},
};
@@ -2788,7 +2752,13 @@ fn zirStructDecl(
const ip = &mod.intern_pool;
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
const extra = sema.code.extraData(Zir.Inst.StructDecl, extended.operand);
- const src: LazySrcLoc = .{ .node_abs = extra.data.src_node };
+
+ const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst);
+ const src: LazySrcLoc = .{
+ .base_node_inst = tracked_inst,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ };
+
var extra_index = extra.end;
const captures_len = if (small.has_captures_len) blk: {
@@ -2832,7 +2802,7 @@ fn zirStructDecl(
.any_aligned_fields = small.any_aligned_fields,
.has_namespace = true or decls_len > 0, // TODO: see below
.key = .{ .declared = .{
- .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
+ .zir_index = tracked_inst,
.captures = captures,
} },
};
@@ -2847,7 +2817,6 @@ fn zirStructDecl(
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
block,
- extra.data.src_node,
Value.fromInterned(wip_ty.index),
small.name_strategy,
"struct",
@@ -2884,7 +2853,6 @@ fn zirStructDecl(
fn createAnonymousDeclTypeNamed(
sema: *Sema,
block: *Block,
- src_node: std.zig.Ast.Node.Index,
val: Value,
name_strategy: Zir.Inst.NameStrategy,
anon_prefix: []const u8,
@@ -2895,7 +2863,7 @@ fn createAnonymousDeclTypeNamed(
const gpa = sema.gpa;
const namespace = block.namespace;
const src_decl = zcu.declPtr(block.src_decl);
- const new_decl_index = try zcu.allocateNewDecl(namespace, src_node);
+ const new_decl_index = try zcu.allocateNewDecl(namespace);
errdefer zcu.destroyDecl(new_decl_index);
switch (name_strategy) {
@@ -2924,8 +2892,7 @@ fn createAnonymousDeclTypeNamed(
// If not then this is a struct type being returned from a non-generic
// function and the name doesn't matter since it will later
// result in a compile error.
- const arg_val = sema.resolveConstValue(block, .unneeded, arg, undefined) catch
- break :func_strat; // fall through to anon strat
+ const arg_val = try sema.resolveValue(arg) orelse break :func_strat; // fall through to anon strat
if (arg_i != 0) try writer.writeByte(',');
@@ -3003,7 +2970,9 @@ fn zirEnumDecl(
const extra = sema.code.extraData(Zir.Inst.EnumDecl, extended.operand);
var extra_index: usize = extra.end;
- const src: LazySrcLoc = .{ .node_abs = extra.data.src_node };
+ const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst);
+ const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) };
+ const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = 0 } };
const tag_type_ref = if (small.has_tag_type) blk: {
const tag_type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
@@ -3063,7 +3032,7 @@ fn zirEnumDecl(
.explicit,
.fields_len = fields_len,
.key = .{ .declared = .{
- .zir_index = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst),
+ .zir_index = tracked_inst,
.captures = captures,
} },
};
@@ -3083,7 +3052,6 @@ fn zirEnumDecl(
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
block,
- extra.data.src_node,
Value.fromInterned(wip_ty.index),
small.name_strategy,
"enum",
@@ -3149,12 +3117,10 @@ fn zirEnumDecl(
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = tracked_inst,
};
defer enum_block.instructions.deinit(sema.gpa);
- // This source location applies in the context of `enum_block`.
- const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = 0 };
-
if (body.len != 0) {
_ = try sema.analyzeInlineBody(&enum_block, body, inst);
}
@@ -3199,36 +3165,33 @@ fn zirEnumDecl(
const field_name = try mod.intern_pool.getOrPutString(gpa, field_name_zir, .no_embedded_nulls);
+ const value_src: LazySrcLoc = .{
+ .base_node_inst = tracked_inst,
+ .offset = .{ .container_field_value = field_i },
+ };
+
const tag_overflow = if (has_tag_value) overflow: {
const tag_val_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
extra_index += 1;
const tag_inst = try sema.resolveInst(tag_val_ref);
- last_tag_val = sema.resolveConstDefinedValue(block, .unneeded, tag_inst, undefined) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const value_src = mod.fieldSrcLoc(new_decl_index, .{
- .index = field_i,
- .range = .value,
- }).lazy;
- _ = try sema.resolveConstDefinedValue(block, value_src, tag_inst, .{
- .needed_comptime_reason = "enum tag value must be comptime-known",
- });
- unreachable;
- },
- else => |e| return e,
- };
+ last_tag_val = try sema.resolveConstDefinedValue(block, .{
+ .base_node_inst = tracked_inst,
+ .offset = .{ .container_field_name = field_i },
+ }, tag_inst, .{
+ .needed_comptime_reason = "enum tag value must be comptime-known",
+ });
if (!(try sema.intFitsInType(last_tag_val.?, int_tag_ty, null))) break :overflow true;
last_tag_val = try mod.getCoerced(last_tag_val.?, int_tag_ty);
if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {
assert(conflict.kind == .value); // AstGen validated names are unique
- const value_src = mod.fieldSrcLoc(new_decl_index, .{
- .index = field_i,
- .range = .value,
- }).lazy;
- const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy;
+ const other_field_src: LazySrcLoc = .{
+ .base_node_inst = tracked_inst,
+ .offset = .{ .container_field_value = conflict.prev_field_idx },
+ };
const msg = msg: {
- const msg = try sema.errMsg(block, value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)});
+ const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)});
errdefer msg.destroy(gpa);
- try sema.errNote(block, other_field_src, msg, "other occurrence here", .{});
+ try sema.errNote(other_field_src, msg, "other occurrence here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -3243,12 +3206,14 @@ fn zirEnumDecl(
if (overflow != null) break :overflow true;
if (wip_ty.nextField(&mod.intern_pool, field_name, last_tag_val.?.toIntern())) |conflict| {
assert(conflict.kind == .value); // AstGen validated names are unique
- const field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = field_i }).lazy;
- const other_field_src = mod.fieldSrcLoc(new_decl_index, .{ .index = conflict.prev_field_idx }).lazy;
+ const other_field_src: LazySrcLoc = .{
+ .base_node_inst = tracked_inst,
+ .offset = .{ .container_field_value = conflict.prev_field_idx },
+ };
const msg = msg: {
- const msg = try sema.errMsg(block, field_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)});
+ const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{last_tag_val.?.fmtValue(sema.mod, sema)});
errdefer msg.destroy(gpa);
- try sema.errNote(block, other_field_src, msg, "other occurrence here", .{});
+ try sema.errNote(other_field_src, msg, "other occurrence here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -3263,11 +3228,7 @@ fn zirEnumDecl(
};
if (tag_overflow) {
- const value_src = mod.fieldSrcLoc(new_decl_index, .{
- .index = field_i,
- .range = if (has_tag_value) .value else .name,
- }).lazy;
- const msg = try sema.errMsg(block, value_src, "enumeration value '{}' too large for type '{}'", .{
+ const msg = try sema.errMsg(value_src, "enumeration value '{}' too large for type '{}'", .{
last_tag_val.?.fmtValue(mod, sema), int_tag_ty.fmt(mod),
});
return sema.failWithOwnedErrorMsg(block, msg);
@@ -3294,7 +3255,8 @@ fn zirUnionDecl(
const extra = sema.code.extraData(Zir.Inst.UnionDecl, extended.operand);
var extra_index: usize = extra.end;
- const src: LazySrcLoc = .{ .node_abs = extra.data.src_node };
+ const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst);
+ const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) };
extra_index += @intFromBool(small.has_tag_type);
const captures_len = if (small.has_captures_len) blk: {
@@ -3342,7 +3304,7 @@ fn zirUnionDecl(
.field_types = &.{}, // set later
.field_aligns = &.{}, // set later
.key = .{ .declared = .{
- .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
+ .zir_index = tracked_inst,
.captures = captures,
} },
};
@@ -3357,7 +3319,6 @@ fn zirUnionDecl(
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
block,
- extra.data.src_node,
Value.fromInterned(wip_ty.index),
small.name_strategy,
"union",
@@ -3409,7 +3370,8 @@ fn zirOpaqueDecl(
const extra = sema.code.extraData(Zir.Inst.OpaqueDecl, extended.operand);
var extra_index: usize = extra.end;
- const src: LazySrcLoc = .{ .node_abs = extra.data.src_node };
+ const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst);
+ const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) };
const captures_len = if (small.has_captures_len) blk: {
const captures_len = sema.code.extra[extra_index];
@@ -3429,7 +3391,7 @@ fn zirOpaqueDecl(
const opaque_init: InternPool.OpaqueTypeInit = .{
.has_namespace = decls_len != 0,
.key = .{ .declared = .{
- .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
+ .zir_index = tracked_inst,
.captures = captures,
} },
};
@@ -3445,7 +3407,6 @@ fn zirOpaqueDecl(
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
block,
- extra.data.src_node,
Value.fromInterned(wip_ty.index),
small.name_strategy,
"opaque",
@@ -3566,19 +3527,19 @@ fn ensureResultUsed(
.ErrorSet => return sema.fail(block, src, "error set is ignored", .{}),
.ErrorUnion => {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "error union is ignored", .{});
+ const msg = try sema.errMsg(src, "error union is ignored", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{});
+ try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
},
else => {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "value of type '{}' ignored", .{ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(src, "value of type '{}' ignored", .{ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "all non-void values must be used", .{});
- try sema.errNote(block, src, msg, "to discard the value, assign it to '_'", .{});
+ try sema.errNote(src, msg, "all non-void values must be used", .{});
+ try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -3599,9 +3560,9 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
.ErrorSet => return sema.fail(block, src, "error set is discarded", .{}),
.ErrorUnion => {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "error union is discarded", .{});
+ const msg = try sema.errMsg(src, "error union is discarded", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{});
+ try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -3627,9 +3588,9 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index
const payload_ty = err_union_ty.errorUnionPayload(mod).zigTypeTag(mod);
if (payload_ty != .Void and payload_ty != .NoReturn) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "error union payload is ignored", .{});
+ const msg = try sema.errMsg(src, "error union payload is ignored", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "payload value can be explicitly ignored with '|_|'", .{});
+ try sema.errNote(src, msg, "payload value can be explicitly ignored with '|_|'", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -3683,8 +3644,8 @@ fn zirAllocExtended(
) CompileError!Air.Inst.Ref {
const gpa = sema.gpa;
const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
- const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = extra.data.src_node };
- const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = extra.data.src_node };
+ const ty_src = block.src(.{ .node_offset_var_decl_ty = extra.data.src_node });
+ const align_src = block.src(.{ .node_offset_var_decl_align = extra.data.src_node });
const small: Zir.Inst.AllocExtended.Small = @bitCast(extended.small);
var extra_index: usize = extra.end;
@@ -3760,7 +3721,7 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
+ const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
return sema.analyzeComptimeAlloc(block, var_ty, .none);
}
@@ -3826,7 +3787,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
if (try sema.typeRequiresComptime(elem_ty)) {
// The value was initialized through RLS, so we didn't detect the runtime condition earlier.
// TODO: source location of runtime control flow
- const init_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const init_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
return sema.fail(block, init_src, "value with comptime-only type '{}' depends on runtime control flow", .{elem_ty.fmt(mod)});
}
@@ -3995,7 +3956,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
.ty = opt_ty.toIntern(),
.val = payload_val.toIntern(),
} });
- try sema.storePtrVal(block, .unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty);
+ try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty);
break :ptr (try Value.fromInterned(decl_parent_ptr).ptrOptPayload(sema)).toIntern();
},
.eu_payload => ptr: {
@@ -4008,7 +3969,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
.ty = eu_ty.toIntern(),
.val = .{ .payload = payload_val.toIntern() },
} });
- try sema.storePtrVal(block, .unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty);
+ try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty);
break :ptr (try Value.fromInterned(decl_parent_ptr).ptrEuPayload(sema)).toIntern();
},
.field => |idx| ptr: {
@@ -4021,7 +3982,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try zcu.undefValue(payload_ty);
const tag_val = try zcu.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), idx);
const store_val = try zcu.unionValue(maybe_union_ty, tag_val, payload_val);
- try sema.storePtrVal(block, .unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
+ try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
}
break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, sema)).toIntern();
},
@@ -4043,14 +4004,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
const air_ptr_inst = store_inst.data.bin_op.lhs.toIndex().?;
const store_val = (try sema.resolveValue(store_inst.data.bin_op.rhs)).?;
const new_ptr = ptr_mapping.get(air_ptr_inst).?;
- try sema.storePtrVal(block, .unneeded, Value.fromInterned(new_ptr), store_val, Type.fromInterned(zcu.intern_pool.typeOf(store_val.toIntern())));
+ try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(new_ptr), store_val, Type.fromInterned(zcu.intern_pool.typeOf(store_val.toIntern())));
},
else => unreachable,
}
}
// The value is finalized - load it!
- const val = (try sema.pointerDeref(block, .unneeded, Value.fromInterned(alloc_ptr), alloc_ty)).?.toIntern();
+ const val = (try sema.pointerDeref(block, LazySrcLoc.unneeded, Value.fromInterned(alloc_ptr), alloc_ty)).?.toIntern();
return sema.finishResolveComptimeKnownAllocPtr(block, alloc_ty, val, ct_alloc, alloc_inst, comptime_info.value);
}
@@ -4153,7 +4114,7 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
+ const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
if (block.is_comptime) {
return sema.analyzeComptimeAlloc(block, var_ty, .none);
@@ -4176,7 +4137,7 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
+ const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
if (block.is_comptime) {
return sema.analyzeComptimeAlloc(block, var_ty, .none);
@@ -4236,7 +4197,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
const gpa = sema.gpa;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
+ const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
const ptr = try sema.resolveInst(inst_data.operand);
const ptr_inst = ptr.toIndex().?;
const target = mod.getTarget();
@@ -4399,20 +4360,20 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
.Int, .ComptimeInt => true,
else => false,
};
- const arg_src: LazySrcLoc = .{ .for_input = .{
+ const arg_src = block.src(.{ .for_input = .{
.for_node_offset = inst_data.src_node,
.input_index = i,
- } };
+ } });
const arg_len_uncoerced = if (is_int) object else l: {
if (!object_ty.isIndexable(mod)) {
// Instead of using checkIndexable we customize this error.
const msg = msg: {
- const msg = try sema.errMsg(block, arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(arg_src, "type '{}' is not indexable and not a range", .{object_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{});
+ try sema.errNote(arg_src, msg, "for loop operand must be a range, array, slice, tuple, or vector", .{});
if (object_ty.zigTypeTag(mod) == .ErrorUnion) {
- try sema.errNote(block, arg_src, msg, "consider using 'try', 'catch', or 'if'", .{});
+ try sema.errNote(arg_src, msg, "consider using 'try', 'catch', or 'if'", .{});
}
break :msg msg;
@@ -4432,16 +4393,16 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
if (len_val) |v| {
if (!(try sema.valuesEqual(arg_val, v, Type.usize))) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "non-matching for loop lengths", .{});
+ const msg = try sema.errMsg(src, "non-matching for loop lengths", .{});
errdefer msg.destroy(gpa);
- const a_src: LazySrcLoc = .{ .for_input = .{
+ const a_src = block.src(.{ .for_input = .{
.for_node_offset = inst_data.src_node,
.input_index = len_idx,
- } };
- try sema.errNote(block, a_src, msg, "length {} here", .{
+ } });
+ try sema.errNote(a_src, msg, "length {} here", .{
v.fmtValue(sema.mod, sema),
});
- try sema.errNote(block, arg_src, msg, "length {} here", .{
+ try sema.errNote(arg_src, msg, "length {} here", .{
arg_val.fmtValue(sema.mod, sema),
});
break :msg msg;
@@ -4461,7 +4422,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
if (len == .none) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "unbounded for loop", .{});
+ const msg = try sema.errMsg(src, "unbounded for loop", .{});
errdefer msg.destroy(gpa);
for (args, 0..) |zir_arg, i_usize| {
const i: u32 = @intCast(i_usize);
@@ -4474,11 +4435,11 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
.Int, .ComptimeInt => continue,
else => {},
}
- const arg_src: LazySrcLoc = .{ .for_input = .{
+ const arg_src = block.src(.{ .for_input = .{
.for_node_offset = inst_data.src_node,
.input_index = i,
- } };
- try sema.errNote(block, arg_src, msg, "type '{}' has no upper bound", .{
+ } });
+ try sema.errNote(arg_src, msg, "type '{}' has no upper bound", .{
object_ty.fmt(sema.mod),
});
}
@@ -4528,7 +4489,7 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
const src = block.nodeOffset(pl_node.src_node);
const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
const uncoerced_val = try sema.resolveInst(extra.rhs);
- const maybe_wrapped_ptr_ty = sema.resolveType(block, .unneeded, extra.lhs) catch |err| switch (err) {
+ const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, extra.lhs) catch |err| switch (err) {
error.GenericPoison => return uncoerced_val,
else => |e| return e,
};
@@ -4590,9 +4551,9 @@ fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
if (ty_operand.isGenericPoison()) return;
if (ty_operand.optEuBaseType(mod).zigTypeTag(mod) != .Pointer) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "expected type '{}', found pointer", .{ty_operand.fmt(mod)});
+ const msg = try sema.errMsg(src, "expected type '{}', found pointer", .{ty_operand.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "address-of operator always returns a pointer", .{});
+ try sema.errNote(src, msg, "address-of operator always returns a pointer", .{});
break :msg msg;
});
}
@@ -4607,7 +4568,7 @@ fn zirValidateArrayInitRefTy(
const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(pl_node.src_node);
const extra = sema.code.extraData(Zir.Inst.ArrayInitRefTy, pl_node.payload_index).data;
- const maybe_wrapped_ptr_ty = sema.resolveType(block, .unneeded, extra.ptr_ty) catch |err| switch (err) {
+ const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, extra.ptr_ty) catch |err| switch (err) {
error.GenericPoison => return .generic_poison_type,
else => |e| return e,
};
@@ -4648,7 +4609,7 @@ fn zirValidateArrayInitTy(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const ty_src: LazySrcLoc = if (is_result_ty) src else .{ .node_offset_init_ty = inst_data.src_node };
+ const ty_src: LazySrcLoc = if (is_result_ty) src else block.src(.{ .node_offset_init_ty = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.ArrayInit, inst_data.payload_index).data;
const ty = sema.resolveType(block, ty_src, extra.ty) catch |err| switch (err) {
// It's okay for the type to be unknown: this will result in an anonymous array init.
@@ -4774,7 +4735,6 @@ fn validateUnionInit(
if (instrs.len != 1) {
const msg = msg: {
const msg = try sema.errMsg(
- block,
init_src,
"cannot initialize multiple union fields at once; unions can only have one active field",
.{},
@@ -4783,8 +4743,8 @@ fn validateUnionInit(
for (instrs[1..]) |inst| {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const inst_src: LazySrcLoc = .{ .node_offset_initializer = inst_data.src_node };
- try sema.errNote(block, inst_src, msg, "additional initializer here", .{});
+ const inst_src = block.src(.{ .node_offset_initializer = inst_data.src_node });
+ try sema.errNote(inst_src, msg, "additional initializer here", .{});
}
try sema.addDeclaredHereNote(msg, union_ty);
break :msg msg;
@@ -4801,7 +4761,7 @@ fn validateUnionInit(
const field_ptr = instrs[0];
const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(field_ptr)].pl_node;
- const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
+ const field_src = block.src(.{ .node_offset_initializer = field_ptr_data.src_node });
const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
const field_name = try mod.intern_pool.getOrPutString(
gpa,
@@ -4918,7 +4878,7 @@ fn validateUnionInit(
const new_tag = Air.internedToRef(tag_val.toIntern());
const set_tag_inst = try block.addBinOp(.set_union_tag, union_ptr, new_tag);
- try sema.checkComptimeKnownStore(block, set_tag_inst, .unneeded); // `unneeded` since this isn't a "proper" store
+ try sema.checkComptimeKnownStore(block, set_tag_inst, LazySrcLoc.unneeded); // `unneeded` since this isn't a "proper" store
}
fn validateStructInit(
@@ -4944,7 +4904,7 @@ fn validateStructInit(
for (instrs, field_indices) |field_ptr, *field_index| {
const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(field_ptr)].pl_node;
- const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
+ const field_src = block.src(.{ .node_offset_initializer = field_ptr_data.src_node });
const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
struct_ptr_zir_ref = field_ptr_extra.lhs;
const field_name = try ip.getOrPutString(
@@ -4981,18 +4941,18 @@ fn validateStructInit(
const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {
const template = "missing tuple field with index {d}";
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, .{i});
+ try sema.errNote(init_src, msg, template, .{i});
} else {
- root_msg = try sema.errMsg(block, init_src, template, .{i});
+ root_msg = try sema.errMsg(init_src, template, .{i});
}
continue;
};
const template = "missing struct field: {}";
const args = .{field_name.fmt(ip)};
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, args);
+ try sema.errNote(init_src, msg, template, args);
} else {
- root_msg = try sema.errMsg(block, init_src, template, args);
+ root_msg = try sema.errMsg(init_src, template, args);
}
continue;
}
@@ -5007,16 +4967,7 @@ fn validateStructInit(
}
if (root_msg) |msg| {
- if (mod.typeToStruct(struct_ty)) |struct_type| {
- const decl = mod.declPtr(struct_type.decl.unwrap().?);
- const fqn = try decl.fullyQualifiedName(mod);
- try mod.errNoteNonLazy(
- decl.srcLoc(mod),
- msg,
- "struct '{}' declared here",
- .{fqn.fmt(ip)},
- );
- }
+ try sema.addDeclaredHereNote(msg, struct_ty);
root_msg = null;
return sema.failWithOwnedErrorMsg(block, msg);
}
@@ -5118,18 +5069,18 @@ fn validateStructInit(
const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {
const template = "missing tuple field with index {d}";
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, .{i});
+ try sema.errNote(init_src, msg, template, .{i});
} else {
- root_msg = try sema.errMsg(block, init_src, template, .{i});
+ root_msg = try sema.errMsg(init_src, template, .{i});
}
continue;
};
const template = "missing struct field: {}";
const args = .{field_name.fmt(ip)};
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, args);
+ try sema.errNote(init_src, msg, template, args);
} else {
- root_msg = try sema.errMsg(block, init_src, template, args);
+ root_msg = try sema.errMsg(init_src, template, args);
}
continue;
}
@@ -5137,21 +5088,12 @@ fn validateStructInit(
}
if (!struct_is_comptime and !fields_allow_runtime and root_msg == null) {
- root_msg = try sema.errMsg(block, init_src, "runtime value contains reference to comptime var", .{});
- try sema.errNote(block, init_src, root_msg.?, "comptime var pointers are not available at runtime", .{});
+ root_msg = try sema.errMsg(init_src, "runtime value contains reference to comptime var", .{});
+ try sema.errNote(init_src, root_msg.?, "comptime var pointers are not available at runtime", .{});
}
if (root_msg) |msg| {
- if (mod.typeToStruct(struct_ty)) |struct_type| {
- const decl = mod.declPtr(struct_type.decl.unwrap().?);
- const fqn = try decl.fullyQualifiedName(mod);
- try mod.errNoteNonLazy(
- decl.srcLoc(mod),
- msg,
- "struct '{}' declared here",
- .{fqn.fmt(ip)},
- );
- }
+ try sema.addDeclaredHereNote(msg, struct_ty);
root_msg = null;
return sema.failWithOwnedErrorMsg(block, msg);
}
@@ -5253,9 +5195,9 @@ fn zirValidatePtrArrayInit(
if (default_val == .unreachable_value) {
const template = "missing tuple field with index {d}";
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, .{i});
+ try sema.errNote(init_src, msg, template, .{i});
} else {
- root_msg = try sema.errMsg(block, init_src, template, .{i});
+ root_msg = try sema.errMsg(init_src, template, .{i});
}
continue;
}
@@ -5455,15 +5397,13 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
} else if (try sema.typeRequiresComptime(elem_ty)) {
const msg = msg: {
const msg = try sema.errMsg(
- block,
src,
"values of type '{}' must be comptime-known, but operand value is runtime-known",
.{elem_ty.fmt(mod)},
);
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsComptime(msg, src_decl.toSrcLoc(src, mod), elem_ty);
+ try sema.explainWhyTypeIsComptime(msg, src, elem_ty);
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -5475,7 +5415,7 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const destructure_src = LazySrcLoc.nodeOffset(extra.destructure_node);
+ const destructure_src = block.nodeOffset(extra.destructure_node);
const operand = try sema.resolveInst(extra.operand);
const operand_ty = sema.typeOf(operand);
@@ -5487,21 +5427,21 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
if (!can_destructure) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "type '{}' cannot be destructured", .{operand_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "type '{}' cannot be destructured", .{operand_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, destructure_src, msg, "result destructured here", .{});
+ try sema.errNote(destructure_src, msg, "result destructured here", .{});
break :msg msg;
});
}
if (operand_ty.arrayLen(mod) != extra.expect_len) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "expected {} elements for destructure, found {}", .{
+ const msg = try sema.errMsg(src, "expected {} elements for destructure, found {}", .{
extra.expect_len,
operand_ty.arrayLen(mod),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, destructure_src, msg, "result destructured here", .{});
+ try sema.errNote(destructure_src, msg, "result destructured here", .{});
break :msg msg;
});
}
@@ -5536,24 +5476,24 @@ fn failWithBadMemberAccess(
fn failWithBadStructFieldAccess(
sema: *Sema,
block: *Block,
+ struct_ty: Type,
struct_type: InternPool.LoadedStructType,
field_src: LazySrcLoc,
field_name: InternPool.NullTerminatedString,
) CompileError {
- const mod = sema.mod;
+ const zcu = sema.mod;
const gpa = sema.gpa;
- const decl = mod.declPtr(struct_type.decl.unwrap().?);
- const fqn = try decl.fullyQualifiedName(mod);
+ const decl = zcu.declPtr(struct_type.decl.unwrap().?);
+ const fqn = try decl.fullyQualifiedName(zcu);
const msg = msg: {
const msg = try sema.errMsg(
- block,
field_src,
"no field named '{}' in struct '{}'",
- .{ field_name.fmt(&mod.intern_pool), fqn.fmt(&mod.intern_pool) },
+ .{ field_name.fmt(&zcu.intern_pool), fqn.fmt(&zcu.intern_pool) },
);
errdefer msg.destroy(gpa);
- try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "struct declared here", .{});
+ try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -5562,25 +5502,25 @@ fn failWithBadStructFieldAccess(
fn failWithBadUnionFieldAccess(
sema: *Sema,
block: *Block,
+ union_ty: Type,
union_obj: InternPool.LoadedUnionType,
field_src: LazySrcLoc,
field_name: InternPool.NullTerminatedString,
) CompileError {
- const mod = sema.mod;
+ const zcu = sema.mod;
const gpa = sema.gpa;
- const decl = mod.declPtr(union_obj.decl);
- const fqn = try decl.fullyQualifiedName(mod);
+ const decl = zcu.declPtr(union_obj.decl);
+ const fqn = try decl.fullyQualifiedName(zcu);
const msg = msg: {
const msg = try sema.errMsg(
- block,
field_src,
"no field named '{}' in union '{}'",
- .{ field_name.fmt(&mod.intern_pool), fqn.fmt(&mod.intern_pool) },
+ .{ field_name.fmt(&zcu.intern_pool), fqn.fmt(&zcu.intern_pool) },
);
errdefer msg.destroy(gpa);
- try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "union declared here", .{});
+ try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -5588,16 +5528,15 @@ fn failWithBadUnionFieldAccess(
fn addDeclaredHereNote(sema: *Sema, parent: *Module.ErrorMsg, decl_ty: Type) !void {
const mod = sema.mod;
- const src_loc = decl_ty.declSrcLocOrNull(mod) orelse return;
+ const src_loc = decl_ty.srcLocOrNull(mod) orelse return;
const category = switch (decl_ty.zigTypeTag(mod)) {
.Union => "union",
.Struct => "struct",
.Enum => "enum",
.Opaque => "opaque",
- .ErrorSet => "error set",
else => unreachable,
};
- try mod.errNoteNonLazy(src_loc, parent, "{s} declared here", .{category});
+ try sema.errNote(src_loc, parent, "{s} declared here", .{category});
}
fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
@@ -5722,8 +5661,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
else => {},
};
- const ptr_src: LazySrcLoc = .{ .node_offset_store_ptr = inst_data.src_node };
- const operand_src: LazySrcLoc = .{ .node_offset_store_operand = inst_data.src_node };
+ const ptr_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });
+ const operand_src = block.src(.{ .node_offset_store_operand = inst_data.src_node });
const air_tag: Air.Inst.Tag = if (is_ret)
.ret_ptr
else if (block.wantSafety())
@@ -5837,7 +5776,7 @@ fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const msg = try sema.resolveConstString(block, operand_src, inst_data.operand, .{
.needed_comptime_reason = "compile error string must be comptime-known",
});
@@ -5846,6 +5785,7 @@ fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
fn zirCompileLog(
sema: *Sema,
+ block: *Block,
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
@@ -5878,9 +5818,10 @@ fn zirCompileLog(
else
sema.owner_decl_index;
const gop = try mod.compile_log_decls.getOrPut(sema.gpa, decl_index);
- if (!gop.found_existing) {
- gop.value_ptr.* = src_node;
- }
+ if (!gop.found_existing) gop.value_ptr.* = .{
+ .base_node_inst = block.src_base_inst,
+ .node_offset = src_node,
+ };
return .void_value;
}
@@ -5891,7 +5832,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
// `panicWithMsg` would perform this coercion for us, but we can get a better
// source location if we do it here.
- const coerced_msg = try sema.coerce(block, Type.slice_const_u8, msg_inst, .{ .node_offset_builtin_call_arg0 = inst_data.src_node });
+ const coerced_msg = try sema.coerce(block, Type.slice_const_u8, msg_inst, block.builtinCallArgSrc(inst_data.src_node, 0));
if (block.is_comptime) {
return sema.fail(block, src, "encountered @panic at comptime", .{});
@@ -5901,7 +5842,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
fn zirTrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node;
- const src = LazySrcLoc.nodeOffset(src_node);
+ const src = block.nodeOffset(src_node);
if (block.is_comptime)
return sema.fail(block, src, "encountered @trap at comptime", .{});
_ = try block.addNoOp(.trap);
@@ -5948,7 +5889,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
var child_block = parent_block.makeSubBlock();
child_block.label = &label;
child_block.runtime_cond = null;
- child_block.runtime_loop = mod.declPtr(child_block.src_decl).toSrcLoc(src, mod);
+ child_block.runtime_loop = src;
child_block.runtime_index.increment();
const merges = &child_block.label.?.merges;
@@ -5997,10 +5938,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
var c_import_buf = std.ArrayList(u8).init(gpa);
defer c_import_buf.deinit();
- var comptime_reason: Block.ComptimeReason = .{ .c_import = .{
- .block = parent_block,
- .src = src,
- } };
+ const comptime_reason: Block.ComptimeReason = .{ .c_import = .{ .src = src } };
var child_block: Block = .{
.parent = parent_block,
.sema = sema,
@@ -6014,6 +5952,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
.runtime_cond = parent_block.runtime_cond,
.runtime_loop = parent_block.runtime_loop,
.runtime_index = parent_block.runtime_index,
+ .src_base_inst = parent_block.src_base_inst,
};
defer child_block.instructions.deinit(gpa);
@@ -6025,11 +5964,11 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
if (c_import_res.errors.errorMessageCount() != 0) {
const msg = msg: {
- const msg = try sema.errMsg(&child_block, src, "C import failed", .{});
+ const msg = try sema.errMsg(src, "C import failed", .{});
errdefer msg.destroy(gpa);
if (!comp.config.link_libc)
- try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{});
+ try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{});
const gop = try mod.cimport_errors.getOrPut(gpa, sema.owner_decl_index);
if (!gop.found_existing) {
@@ -6139,6 +6078,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_compt
.runtime_loop = parent_block.runtime_loop,
.runtime_index = parent_block.runtime_index,
.error_return_trace_index = parent_block.error_return_trace_index,
+ .src_base_inst = parent_block.src_base_inst,
};
defer child_block.instructions.deinit(gpa);
@@ -6333,14 +6273,13 @@ fn resolveAnalyzedBlock(
const type_src = src; // TODO: better source location
if (try sema.typeRequiresComptime(resolved_ty)) {
const msg = msg: {
- const msg = try sema.errMsg(child_block, type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(mod)});
+ const msg = try sema.errMsg(type_src, "value with comptime-only type '{}' depends on runtime control flow", .{resolved_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
- try mod.errNoteNonLazy(runtime_src, msg, "runtime control flow here", .{});
+ try sema.errNote(runtime_src, msg, "runtime control flow here", .{});
- const child_src_decl = mod.declPtr(child_block.src_decl);
- try sema.explainWhyTypeIsComptime(msg, child_src_decl.toSrcLoc(type_src, mod), resolved_ty);
+ try sema.explainWhyTypeIsComptime(msg, type_src, resolved_ty);
break :msg msg;
};
@@ -6433,8 +6372,8 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Export, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const decl_name = try mod.intern_pool.getOrPutString(
mod.gpa,
sema.code.nullTerminatedString(extra.decl_name),
@@ -6448,13 +6387,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
break :index_blk maybe_index orelse
return sema.failWithBadMemberAccess(block, container_ty, operand_src, decl_name);
} else try sema.lookupIdentifier(block, operand_src, decl_name);
- const options = sema.resolveExportOptions(block, .unneeded, extra.options) catch |err| switch (err) {
- error.NeededSourceLocation => {
- _ = try sema.resolveExportOptions(block, options_src, extra.options);
- unreachable;
- },
- else => |e| return e,
- };
+ const options = try sema.resolveExportOptions(block, options_src, extra.options);
{
try sema.ensureDeclAnalyzed(decl_index);
const exported_decl = mod.declPtr(decl_index);
@@ -6473,8 +6406,8 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const operand = try sema.resolveInstConst(block, operand_src, extra.operand, .{
.needed_comptime_reason = "export target must be comptime-known",
});
@@ -6490,7 +6423,6 @@ fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
.opts = options,
.src = src,
.owner_decl = sema.owner_decl_index,
- .src_decl = block.src_decl,
.exported = .{ .value = operand.toIntern() },
.status = .in_progress,
});
@@ -6515,11 +6447,10 @@ pub fn analyzeExport(
if (!try sema.validateExternType(export_ty, .other)) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{export_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "unable to export type '{}'", .{export_ty.fmt(mod)});
errdefer msg.destroy(gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), export_ty, .other);
+ try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
try sema.addDeclaredHereNote(msg, export_ty);
break :msg msg;
@@ -6538,7 +6469,6 @@ pub fn analyzeExport(
.opts = options,
.src = src,
.owner_decl = sema.owner_decl_index,
- .src_decl = block.src_decl,
.exported = .{ .decl_index = exported_decl_index },
.status = .in_progress,
});
@@ -6578,8 +6508,8 @@ fn addExport(mod: *Module, export_init: Module.Export) error{OutOfMemory}!void {
fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
const mod = sema.mod;
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const src = LazySrcLoc.nodeOffset(extra.node);
+ const operand_src = block.builtinCallArgSrc(extra.node, 0);
+ const src = block.nodeOffset(extra.node);
const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) {
return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
@@ -6598,9 +6528,9 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
if (sema.prev_stack_alignment_src) |prev_src| {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "multiple @setAlignStack in the same function body", .{});
+ const msg = try sema.errMsg(src, "multiple @setAlignStack in the same function body", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, prev_src, msg, "other instance here", .{});
+ try sema.errNote(prev_src, msg, "other instance here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -6621,7 +6551,7 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
const mod = sema.mod;
const ip = &mod.intern_pool;
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const operand_src = block.builtinCallArgSrc(extra.node, 0);
const is_cold = try sema.resolveConstBool(block, operand_src, extra.operand, .{
.needed_comptime_reason = "operand to @setCold must be comptime-known",
});
@@ -6631,7 +6561,7 @@ fn zirSetCold(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src = block.builtinCallArgSrc(extra.node, 0);
block.float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode", .{
.needed_comptime_reason = "operand to @setFloatMode must be comptime-known",
});
@@ -6639,7 +6569,7 @@ fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand, .{
.needed_comptime_reason = "operand to @setRuntimeSafety must be comptime-known",
});
@@ -6649,7 +6579,7 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co
if (block.is_comptime) return;
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const order_src = block.builtinCallArgSrc(extra.node, 0);
const order = try sema.resolveAtomicOrder(block, order_src, extra.operand, .{
.needed_comptime_reason = "atomic order of @fence must be comptime-known",
});
@@ -6679,7 +6609,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
if (label.zir_block == zir_block) {
const br_ref = try start_block.addBr(label.merges.block_inst, operand);
const src_loc = if (extra.operand_src_node != Zir.Inst.Break.no_src_node)
- LazySrcLoc.nodeOffset(extra.operand_src_node)
+ start_block.nodeOffset(extra.operand_src_node)
else
null;
try label.merges.src_locs.append(sema.gpa, src_loc);
@@ -6906,12 +6836,14 @@ fn lookupInNamespace(
},
else => {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "ambiguous reference", .{});
+ const msg = try sema.errMsg(src, "ambiguous reference", .{});
errdefer msg.destroy(gpa);
for (candidates.items) |candidate_index| {
const candidate = mod.declPtr(candidate_index);
- const src_loc = candidate.srcLoc(mod);
- try mod.errNoteNonLazy(src_loc, msg, "declared here", .{});
+ try sema.errNote(.{
+ .base_node_inst = candidate.zir_decl_index.unwrap().?,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ }, msg, "declared here", .{});
}
break :msg msg;
};
@@ -6953,16 +6885,16 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
if (!block.ownerModule().error_tracing) return .none;
const stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) {
- error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
+ error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
else => |e| return e,
};
sema.resolveTypeFields(stack_trace_ty) catch |err| switch (err) {
- error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
+ error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
else => |e| return e,
};
const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
- const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, .unneeded) catch |err| switch (err) {
- error.AnalysisFail, error.NeededSourceLocation => @panic("std.builtin.StackTrace is corrupt"),
+ const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
+ error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),
error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
error.OutOfMemory => |e| return e,
};
@@ -7070,7 +7002,7 @@ fn zirCall(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const callee_src: LazySrcLoc = .{ .node_offset_call_func = inst_data.src_node };
+ const callee_src = block.src(.{ .node_offset_call_func = inst_data.src_node });
const call_src = block.nodeOffset(inst_data.src_node);
const ExtraType = switch (kind) {
.direct => Zir.Inst.Call,
@@ -7092,7 +7024,7 @@ fn zirCall(
sema.code.nullTerminatedString(extra.data.field_name_start),
.no_embedded_nulls,
);
- const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
+ const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });
break :blk try sema.fieldCallBind(block, callee_src, object_ptr, field_name, field_name_src);
},
};
@@ -7202,11 +7134,11 @@ fn checkCallArgumentCount(
opt_child.childType(mod).zigTypeTag(mod) == .Fn))
{
const msg = msg: {
- const msg = try sema.errMsg(block, func_src, "cannot call optional type '{}'", .{
+ const msg = try sema.errMsg(func_src, "cannot call optional type '{}'", .{
callee_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, func_src, msg, "consider using '.?', 'orelse' or 'if'", .{});
+ try sema.errNote(func_src, msg, "consider using '.?', 'orelse' or 'if'", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -7232,7 +7164,6 @@ fn checkCallArgumentCount(
const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
const msg = msg: {
const msg = try sema.errMsg(
- block,
func_src,
"{s}expected {s}{d} argument(s), found {d}",
.{
@@ -7244,7 +7175,12 @@ fn checkCallArgumentCount(
);
errdefer msg.destroy(sema.gpa);
- if (maybe_decl) |fn_decl| try mod.errNoteNonLazy(fn_decl.srcLoc(mod), msg, "function declared here", .{});
+ if (maybe_decl) |fn_decl| {
+ try sema.errNote(.{
+ .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ }, msg, "function declared here", .{});
+ }
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -7352,18 +7288,16 @@ const CallArgsInfo = union(enum) {
fn argSrc(cai: CallArgsInfo, block: *Block, arg_index: usize) LazySrcLoc {
return switch (cai) {
.resolved => |resolved| resolved.src,
- .call_builtin => |call_builtin| .{ .call_arg = .{
- .decl = block.src_decl,
+ .call_builtin => |call_builtin| block.src(.{ .call_arg = .{
.call_node_offset = call_builtin.call_node_offset,
.arg_index = @intCast(arg_index),
- } },
+ } }),
.zir_call => |zir_call| if (arg_index == 0 and zir_call.bound_arg != .none) {
return zir_call.bound_arg_src;
- } else .{ .call_arg = .{
- .decl = block.src_decl,
+ } else block.src(.{ .call_arg = .{
.call_node_offset = zir_call.call_node_offset,
.arg_index = @intCast(arg_index - @intFromBool(zir_call.bound_arg != .none)),
- } },
+ } }),
};
}
@@ -7475,7 +7409,6 @@ const InlineCallSema = struct {
other_error_return_trace_index_on_fn_entry: Air.Inst.Ref,
other_generic_owner: InternPool.Index,
other_generic_call_src: LazySrcLoc,
- other_generic_call_decl: InternPool.OptionalDeclIndex,
/// Sema should currently be set up for the caller (i.e. unchanged yet). This init will not
/// change that. The other parameters contain data for the callee Sema. The other modified
@@ -7497,8 +7430,7 @@ const InlineCallSema = struct {
.other_inst_map = .{},
.other_error_return_trace_index_on_fn_entry = callee_error_return_trace_index_on_fn_entry,
.other_generic_owner = .none,
- .other_generic_call_src = .unneeded,
- .other_generic_call_decl = .none,
+ .other_generic_call_src = LazySrcLoc.unneeded,
};
}
@@ -7545,7 +7477,6 @@ const InlineCallSema = struct {
std.mem.swap(InstMap, &ics.sema.inst_map, &ics.other_inst_map);
std.mem.swap(InternPool.Index, &ics.sema.generic_owner, &ics.other_generic_owner);
std.mem.swap(LazySrcLoc, &ics.sema.generic_call_src, &ics.other_generic_call_src);
- std.mem.swap(InternPool.OptionalDeclIndex, &ics.sema.generic_call_decl, &ics.other_generic_call_decl);
std.mem.swap(Air.Inst.Ref, &ics.sema.error_return_trace_index_on_fn_entry, &ics.other_error_return_trace_index_on_fn_entry);
// zig fmt: on
}
@@ -7577,14 +7508,16 @@ fn analyzeCall(
const maybe_decl = try sema.funcDeclSrc(func);
const msg = msg: {
const msg = try sema.errMsg(
- block,
func_src,
"unable to call function with naked calling convention",
.{},
);
errdefer msg.destroy(sema.gpa);
- if (maybe_decl) |fn_decl| try mod.errNoteNonLazy(fn_decl.srcLoc(mod), msg, "function declared here", .{});
+ if (maybe_decl) |fn_decl| try sema.errNote(.{
+ .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ }, msg, "function declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -7623,7 +7556,6 @@ fn analyzeCall(
is_inline_call = ct;
if (ct) {
comptime_reason = &.{ .comptime_ret_ty = .{
- .block = block,
.func = func,
.func_src = func_src,
.return_ty = Type.fromInterned(func_ty_info.return_type),
@@ -7637,12 +7569,12 @@ fn analyzeCall(
if (sema.func_is_naked and !is_inline_call and !is_comptime_call) {
const msg = msg: {
- const msg = try sema.errMsg(block, call_src, "runtime {s} not allowed in naked function", .{@tagName(operation)});
+ const msg = try sema.errMsg(call_src, "runtime {s} not allowed in naked function", .{@tagName(operation)});
errdefer msg.destroy(sema.gpa);
switch (operation) {
.call, .@"@call", .@"@panic", .@"error return" => {},
- .@"safety check" => try sema.errNote(block, call_src, msg, "use @setRuntimeSafety to disable runtime safety", .{}),
+ .@"safety check" => try sema.errNote(call_src, msg, "use @setRuntimeSafety to disable runtime safety", .{}),
}
break :msg msg;
};
@@ -7669,7 +7601,6 @@ fn analyzeCall(
is_inline_call = true;
is_comptime_call = true;
comptime_reason = &.{ .comptime_ret_ty = .{
- .block = block,
.func = func,
.func_src = func_src,
.return_ty = Type.fromInterned(func_ty_info.return_type),
@@ -7776,6 +7707,7 @@ fn analyzeCall(
.runtime_cond = block.runtime_cond,
.runtime_loop = block.runtime_loop,
.runtime_index = block.runtime_index,
+ .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,
};
const merges = &child_block.inlining.?.merges;
@@ -7849,7 +7781,7 @@ fn analyzeCall(
var block_it = block;
while (block_it.inlining) |parent_inlining| {
if (!parent_inlining.has_comptime_args and parent_inlining.func == module_fn_index) {
- const err_msg = try sema.errMsg(block, call_src, "inline call is recursive", .{});
+ const err_msg = try sema.errMsg(call_src, "inline call is recursive", .{});
return sema.failWithOwnedErrorMsg(null, err_msg);
}
block_it = parent_inlining.call_block;
@@ -7864,7 +7796,7 @@ fn analyzeCall(
try sema.resolveInlineBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst.resolve(ip))
else
try sema.resolveInst(fn_info.ret_ty_ref);
- const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
+ const ret_ty_src: LazySrcLoc = .{ .base_node_inst = module_fn.zir_body_inst, .offset = .{ .node_offset_fn_type_ret_ty = 0 } };
sema.fn_ret_ty = try sema.analyzeAsType(&child_block, ret_ty_src, ret_ty_inst);
if (module_fn.analysis(ip).inferred_error_set) {
// Create a fresh inferred error set type for inline/comptime calls.
@@ -7935,7 +7867,7 @@ fn analyzeCall(
};
if (is_comptime_call) {
- const result_val = try sema.resolveConstValue(block, .unneeded, result, undefined);
+ const result_val = try sema.resolveConstValue(block, LazySrcLoc.unneeded, result, undefined);
const result_interned = result_val.toIntern();
// Transform ad-hoc inferred error set types into concrete error sets.
@@ -8276,7 +8208,6 @@ fn instantiateGenericCall(
.comptime_args = comptime_args,
.generic_owner = generic_owner,
.generic_call_src = call_src,
- .generic_call_decl = block.src_decl.toOptional(),
.branch_quota = sema.branch_quota,
.branch_count = sema.branch_count,
.comptime_err_ret_trace = sema.comptime_err_ret_trace,
@@ -8291,6 +8222,7 @@ fn instantiateGenericCall(
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?,
};
defer child_block.instructions.deinit(gpa);
@@ -8321,18 +8253,15 @@ fn instantiateGenericCall(
const prev_no_partial_func_ty = child_sema.no_partial_func_ty;
const prev_generic_owner = child_sema.generic_owner;
const prev_generic_call_src = child_sema.generic_call_src;
- const prev_generic_call_decl = child_sema.generic_call_decl;
child_block.params = .{};
child_sema.no_partial_func_ty = true;
child_sema.generic_owner = .none;
- child_sema.generic_call_src = .unneeded;
- child_sema.generic_call_decl = .none;
+ child_sema.generic_call_src = LazySrcLoc.unneeded;
defer {
child_block.params = prev_params;
child_sema.no_partial_func_ty = prev_no_partial_func_ty;
child_sema.generic_owner = prev_generic_owner;
child_sema.generic_call_src = prev_generic_call_src;
- child_sema.generic_call_decl = prev_generic_call_decl;
}
const param_ty_inst = try child_sema.resolveInlineBody(&child_block, param_ty_body, param_inst);
@@ -8372,14 +8301,14 @@ fn instantiateGenericCall(
.param_anytype_comptime,
=> return sema.failWithOwnedErrorMsg(block, msg: {
const arg_src = args_info.argSrc(block, arg_index);
- const msg = try sema.errMsg(block, arg_src, "runtime-known argument passed to comptime parameter", .{});
+ const msg = try sema.errMsg(arg_src, "runtime-known argument passed to comptime parameter", .{});
errdefer msg.destroy(sema.gpa);
const param_src = child_block.tokenOffset(switch (param_tag) {
.param_comptime => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].pl_tok.src_tok,
.param_anytype_comptime => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.src_tok,
else => unreachable,
});
- try child_sema.errNote(&child_block, param_src, msg, "declared comptime here", .{});
+ try child_sema.errNote(param_src, msg, "declared comptime here", .{});
break :msg msg;
}),
@@ -8387,16 +8316,15 @@ fn instantiateGenericCall(
.param_anytype,
=> return sema.failWithOwnedErrorMsg(block, msg: {
const arg_src = args_info.argSrc(block, arg_index);
- const msg = try sema.errMsg(block, arg_src, "runtime-known argument passed to parameter of comptime-only type", .{});
+ const msg = try sema.errMsg(arg_src, "runtime-known argument passed to parameter of comptime-only type", .{});
errdefer msg.destroy(sema.gpa);
const param_src = child_block.tokenOffset(switch (param_tag) {
.param => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].pl_tok.src_tok,
.param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.src_tok,
else => unreachable,
});
- try child_sema.errNote(&child_block, param_src, msg, "declared here", .{});
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsComptime(msg, src_decl.toSrcLoc(arg_src, mod), arg_ty);
+ try child_sema.errNote(param_src, msg, "declared here", .{});
+ try sema.explainWhyTypeIsComptime(msg, arg_src, arg_ty);
break :msg msg;
}),
@@ -8433,7 +8361,7 @@ fn instantiateGenericCall(
// We've already handled parameters, so don't resolve the whole body. Instead, just
// do the instructions after the params (i.e. the func itself).
const new_func_inst = try child_sema.resolveInlineBody(&child_block, fn_info.param_body[args_info.count()..], fn_info.param_body_inst);
- const callee_index = (child_sema.resolveConstDefinedValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable).toIntern();
+ const callee_index = (child_sema.resolveConstDefinedValue(&child_block, LazySrcLoc.unneeded, new_func_inst, undefined) catch unreachable).toIntern();
const callee = mod.funcInfo(callee_index);
callee.branchQuota(ip).* = @max(callee.branchQuota(ip).*, sema.branch_quota);
@@ -8520,7 +8448,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
+ const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
const child_type = try sema.resolveType(block, operand_src, inst_data.operand);
if (child_type.zigTypeTag(mod) == .Opaque) {
return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(mod)});
@@ -8535,7 +8463,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;
- const maybe_wrapped_indexable_ty = sema.resolveType(block, .unneeded, bin.lhs) catch |err| switch (err) {
+ const maybe_wrapped_indexable_ty = sema.resolveType(block, LazySrcLoc.unneeded, bin.lhs) catch |err| switch (err) {
// Since this is a ZIR instruction that returns a type, encountering
// generic poison should not result in a failed compilation, but the
// generic poison type. This prevents unnecessary failures when
@@ -8558,7 +8486,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const maybe_wrapped_ptr_ty = sema.resolveType(block, .unneeded, un_node.operand) catch |err| switch (err) {
+ const maybe_wrapped_ptr_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {
error.GenericPoison => return .generic_poison_type,
else => |e| return e,
};
@@ -8592,7 +8520,7 @@ fn zirIndexablePtrElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const vec_ty = sema.resolveType(block, .unneeded, un_node.operand) catch |err| switch (err) {
+ const vec_ty = sema.resolveType(block, LazySrcLoc.unneeded, un_node.operand) catch |err| switch (err) {
// Since this is a ZIR instruction that returns a type, encountering
// generic poison should not result in a failed compilation, but the
// generic poison type. This prevents unnecessary failures when
@@ -8609,8 +8537,8 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const len_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const elem_type_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const len: u32 = @intCast(try sema.resolveInt(block, len_src, extra.lhs, Type.u32, .{
.needed_comptime_reason = "vector length must be comptime-known",
@@ -8630,8 +8558,8 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node };
- const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node };
+ const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node });
+ const elem_src = block.src(.{ .node_offset_array_type_elem = inst_data.src_node });
const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize, .{
.needed_comptime_reason = "array length must be comptime-known",
});
@@ -8651,9 +8579,9 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.ArrayTypeSentinel, inst_data.payload_index).data;
- const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node };
- const sentinel_src: LazySrcLoc = .{ .node_offset_array_type_sentinel = inst_data.src_node };
- const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node };
+ const len_src = block.src(.{ .node_offset_array_type_len = inst_data.src_node });
+ const sentinel_src = block.src(.{ .node_offset_array_type_sentinel = inst_data.src_node });
+ const elem_src = block.src(.{ .node_offset_array_type_elem = inst_data.src_node });
const len = try sema.resolveInt(block, len_src, extra.len, Type.usize, .{
.needed_comptime_reason = "array length must be comptime-known",
});
@@ -8691,7 +8619,7 @@ fn zirAnyframeType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
return sema.failWithUseOfAsync(block, block.nodeOffset(inst_data.src_node));
}
const mod = sema.mod;
- const operand_src: LazySrcLoc = .{ .node_offset_anyframe_type = inst_data.src_node };
+ const operand_src = block.src(.{ .node_offset_anyframe_type = inst_data.src_node });
const return_type = try sema.resolveType(block, operand_src, inst_data.operand);
const anyframe_type = try mod.anyframeType(return_type);
@@ -8705,8 +8633,8 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const error_set = try sema.resolveType(block, lhs_src, extra.lhs);
const payload = try sema.resolveType(block, rhs_src, extra.rhs);
@@ -8758,8 +8686,8 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
const mod = sema.mod;
const ip = &mod.intern_pool;
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const operand_src = block.builtinCallArgSrc(extra.node, 0);
const uncasted_operand = try sema.resolveInst(extra.operand);
const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);
const err_int_ty = try mod.errorIntType();
@@ -8801,8 +8729,8 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
const mod = sema.mod;
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const operand_src = block.builtinCallArgSrc(extra.node, 0);
const uncasted_operand = try sema.resolveInst(extra.operand);
const err_int_ty = try mod.errorIntType();
const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
@@ -8841,16 +8769,16 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
const ip = &mod.intern_pool;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
if (sema.typeOf(lhs).zigTypeTag(mod) == .Bool and sema.typeOf(rhs).zigTypeTag(mod) == .Bool) {
const msg = msg: {
- const msg = try sema.errMsg(block, lhs_src, "expected error set type, found 'bool'", .{});
+ const msg = try sema.errMsg(lhs_src, "expected error set type, found 'bool'", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "'||' merges error sets; 'or' performs boolean OR", .{});
+ try sema.errNote(src, msg, "'||' merges error sets; 'or' performs boolean OR", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -8905,7 +8833,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand = try sema.resolveInst(inst_data.operand);
const operand_ty = sema.typeOf(operand);
@@ -8963,7 +8891,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@enumFromInt");
const operand = try sema.resolveInst(extra.rhs);
@@ -9379,7 +9307,7 @@ fn zirFunc(
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
const target = sema.mod.getTarget();
- const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = inst_data.src_node };
+ const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
var extra_index = extra.end;
@@ -9460,18 +9388,15 @@ fn resolveGenericBody(
const prev_no_partial_func_type = sema.no_partial_func_ty;
const prev_generic_owner = sema.generic_owner;
const prev_generic_call_src = sema.generic_call_src;
- const prev_generic_call_decl = sema.generic_call_decl;
block.params = .{};
sema.no_partial_func_ty = true;
sema.generic_owner = .none;
- sema.generic_call_src = .unneeded;
- sema.generic_call_decl = .none;
+ sema.generic_call_src = LazySrcLoc.unneeded;
defer {
block.params = prev_params;
sema.no_partial_func_ty = prev_no_partial_func_type;
sema.generic_owner = prev_generic_owner;
sema.generic_call_src = prev_generic_call_src;
- sema.generic_call_decl = prev_generic_call_decl;
}
const uncasted = sema.resolveInlineBody(block, body, func_inst) catch |err| break :err err;
@@ -9581,9 +9506,9 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc:
if (!callConvSupportsVarArgs(cc)) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "variadic function does not support '.{s}' calling convention", .{@tagName(cc)});
+ const msg = try sema.errMsg(src, "variadic function does not support '.{s}' calling convention", .{@tagName(cc)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "supported calling conventions: {}", .{CallingConventionsSupportingVarArgsList{}});
+ try sema.errNote(src, msg, "supported calling conventions: {}", .{CallingConventionsSupportingVarArgsList{}});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -9623,9 +9548,9 @@ fn funcCommon(
const gpa = sema.gpa;
const target = mod.getTarget();
const ip = &mod.intern_pool;
- const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
- const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
- const func_src = LazySrcLoc.nodeOffset(src_node_offset);
+ const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
+ const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
+ const func_src = block.nodeOffset(src_node_offset);
var is_generic = bare_return_type.isGenericPoison() or
alignment == null or
@@ -9654,11 +9579,10 @@ fn funcCommon(
const index = std.math.cast(u5, i) orelse break :blk false;
break :blk @as(u1, @truncate(noalias_bits >> index)) != 0;
};
- const param_src: LazySrcLoc = .{ .fn_proto_param = .{
- .decl = block.src_decl,
+ const param_src = block.src(.{ .fn_proto_param = .{
.fn_proto_node_offset = src_node_offset,
.param_index = @intCast(i),
- } };
+ } });
const requires_comptime = try sema.typeRequiresComptime(param_ty);
if (param_is_comptime or requires_comptime) {
comptime_bits |= @as(u32, 1) << @intCast(i); // TODO: handle cast error
@@ -9679,13 +9603,12 @@ fn funcCommon(
}
if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) {
const msg = msg: {
- const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{
+ const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{
param_ty.fmt(mod), @tagName(cc_resolved),
});
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(param_src, mod), param_ty, .param_ty);
+ try sema.explainWhyTypeIsNotExtern(msg, param_src, param_ty, .param_ty);
try sema.addDeclaredHereNote(msg, param_ty);
break :msg msg;
@@ -9694,13 +9617,12 @@ fn funcCommon(
}
if (is_source_decl and requires_comptime and !param_is_comptime and has_body and !block.is_comptime) {
const msg = msg: {
- const msg = try sema.errMsg(block, param_src, "parameter of type '{}' must be declared comptime", .{
+ const msg = try sema.errMsg(param_src, "parameter of type '{}' must be declared comptime", .{
param_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsComptime(msg, src_decl.toSrcLoc(param_src, mod), param_ty);
+ try sema.explainWhyTypeIsComptime(msg, param_src, param_ty);
try sema.addDeclaredHereNote(msg, param_ty);
break :msg msg;
@@ -9861,9 +9783,9 @@ fn funcCommon(
assert(section != .generic);
assert(address_space != null);
assert(!is_generic);
- if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, .{
+ if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, block.src(.{
.node_offset_lib_name = src_node_offset,
- }, lib_name);
+ }), lib_name);
const func_index = try ip.getExternFunc(gpa, .{
.ty = func_ty,
.decl = sema.owner_decl_index,
@@ -9975,13 +9897,12 @@ fn finishFunc(
!try sema.validateExternType(return_type, .ret_ty))
{
const msg = msg: {
- const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{
+ const msg = try sema.errMsg(ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{
return_type.fmt(mod), @tagName(cc_resolved),
});
errdefer msg.destroy(gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(ret_ty_src, mod), return_type, .ret_ty);
+ try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src, return_type, .ret_ty);
try sema.addDeclaredHereNote(msg, return_type);
break :msg msg;
@@ -9997,12 +9918,11 @@ fn finishFunc(
} else break :comptime_check;
const msg = try sema.errMsg(
- block,
ret_ty_src,
"function with comptime-only return type '{}' requires all parameters to be comptime",
.{return_type.fmt(mod)},
);
- try sema.explainWhyTypeIsComptime(msg, sema.owner_decl.toSrcLoc(ret_ty_src, mod), return_type);
+ try sema.explainWhyTypeIsComptime(msg, ret_ty_src, return_type);
const tags = sema.code.instructions.items(.tag);
const data = sema.code.instructions.items(.data);
@@ -10020,9 +9940,9 @@ fn finishFunc(
});
const name = sema.code.nullTerminatedString(name_nts);
if (name.len != 0) {
- try sema.errNote(block, param_src, msg, "param '{s}' is required to be comptime", .{name});
+ try sema.errNote(param_src, msg, "param '{s}' is required to be comptime", .{name});
} else {
- try sema.errNote(block, param_src, msg, "param is required to be comptime", .{});
+ try sema.errNote(param_src, msg, "param is required to be comptime", .{});
}
}
}
@@ -10112,18 +10032,15 @@ fn zirParam(
const prev_no_partial_func_type = sema.no_partial_func_ty;
const prev_generic_owner = sema.generic_owner;
const prev_generic_call_src = sema.generic_call_src;
- const prev_generic_call_decl = sema.generic_call_decl;
block.params = .{};
sema.no_partial_func_ty = true;
sema.generic_owner = .none;
- sema.generic_call_src = .unneeded;
- sema.generic_call_decl = .none;
+ sema.generic_call_src = LazySrcLoc.unneeded;
defer {
block.params = prev_params;
sema.no_partial_func_ty = prev_no_partial_func_type;
sema.generic_owner = prev_generic_owner;
sema.generic_call_src = prev_generic_call_src;
- sema.generic_call_decl = prev_generic_call_decl;
}
if (sema.resolveInlineBody(block, body, inst)) |param_ty_inst| {
@@ -10265,7 +10182,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const zcu = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand = try sema.resolveInst(inst_data.operand);
const operand_ty = sema.typeOf(operand);
const ptr_ty = operand_ty.scalarType(zcu);
@@ -10276,10 +10193,9 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const pointee_ty = ptr_ty.childType(zcu);
if (try sema.typeRequiresComptime(ptr_ty)) {
const msg = msg: {
- const msg = try sema.errMsg(block, ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(zcu)});
+ const msg = try sema.errMsg(ptr_src, "comptime-only type '{}' has no pointer address", .{pointee_ty.fmt(zcu)});
errdefer msg.destroy(sema.gpa);
- const src_decl = zcu.declPtr(block.src_decl);
- try sema.explainWhyTypeIsComptime(msg, src_decl.toSrcLoc(ptr_src, zcu), pointee_ty);
+ try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty);
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -10340,7 +10256,7 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
+ const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
const field_name = try mod.intern_pool.getOrPutString(
sema.gpa,
@@ -10358,7 +10274,7 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
+ const field_name_src = block.src(.{ .node_offset_field_name = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
const field_name = try mod.intern_pool.getOrPutString(
sema.gpa,
@@ -10376,7 +10292,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const field_name_src: LazySrcLoc = .{ .node_offset_field_name_init = inst_data.src_node };
+ const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
const field_name = try mod.intern_pool.getOrPutString(
sema.gpa,
@@ -10401,7 +10317,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
const object = try sema.resolveInst(extra.lhs);
const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{
@@ -10416,7 +10332,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
const object_ptr = try sema.resolveInst(extra.lhs);
const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{
@@ -10431,7 +10347,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast");
@@ -10601,7 +10517,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@bitCast");
@@ -10627,10 +10543,10 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
.Enum => {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
switch (operand_ty.zigTypeTag(mod)) {
- .Int, .ComptimeInt => try sema.errNote(block, src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(mod)}),
+ .Int, .ComptimeInt => try sema.errNote(src, msg, "use @enumFromInt to cast from '{}'", .{operand_ty.fmt(mod)}),
else => {},
}
@@ -10641,11 +10557,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
.Pointer => {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
switch (operand_ty.zigTypeTag(mod)) {
- .Int, .ComptimeInt => try sema.errNote(block, src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(mod)}),
- .Pointer => try sema.errNote(block, src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(mod)}),
+ .Int, .ComptimeInt => try sema.errNote(src, msg, "use @ptrFromInt to cast from '{}'", .{operand_ty.fmt(mod)}),
+ .Pointer => try sema.errNote(src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(mod)}),
else => {},
}
@@ -10691,10 +10607,10 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
.Enum => {
const msg = msg: {
- const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)});
+ const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
switch (dest_ty.zigTypeTag(mod)) {
- .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(mod)}),
+ .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromEnum to cast to '{}'", .{dest_ty.fmt(mod)}),
else => {},
}
@@ -10704,11 +10620,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
},
.Pointer => {
const msg = msg: {
- const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)});
+ const msg = try sema.errMsg(operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
switch (dest_ty.zigTypeTag(mod)) {
- .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(mod)}),
- .Pointer => try sema.errNote(block, operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(mod)}),
+ .Int, .ComptimeInt => try sema.errNote(operand_src, msg, "use @intFromPtr to cast to '{}'", .{dest_ty.fmt(mod)}),
+ .Pointer => try sema.errNote(operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(mod)}),
else => {},
}
@@ -10744,7 +10660,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatCast");
@@ -10835,7 +10751,7 @@ fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
+ const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const array = try sema.resolveInst(extra.lhs);
const uncoerced_elem_index = try sema.resolveInst(extra.rhs);
@@ -10851,7 +10767,7 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;
const array = try sema.resolveInst(inst_data.operand);
const elem_index = try mod.intRef(Type.usize, inst_data.idx);
- return sema.elemVal(block, .unneeded, array, elem_index, .unneeded, false);
+ return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false);
}
fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -10866,14 +10782,14 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const elem_index = try sema.resolveInst(extra.rhs);
const indexable_ty = sema.typeOf(array_ptr);
if (indexable_ty.zigTypeTag(mod) != .Pointer) {
- const capture_src: LazySrcLoc = .{ .for_capture_from_input = inst_data.src_node };
+ const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node });
const msg = msg: {
- const msg = try sema.errMsg(block, capture_src, "pointer capture of non pointer type '{}'", .{
+ const msg = try sema.errMsg(capture_src, "pointer capture of non pointer type '{}'", .{
indexable_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
if (indexable_ty.isIndexable(mod)) {
- try sema.errNote(block, src, msg, "consider using '&' here", .{});
+ try sema.errNote(src, msg, "consider using '&' here", .{});
}
break :msg msg;
};
@@ -10888,7 +10804,7 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
+ const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const array_ptr = try sema.resolveInst(extra.lhs);
const uncoerced_elem_index = try sema.resolveInst(extra.rhs);
@@ -10925,11 +10841,11 @@ fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const extra = sema.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data;
const array_ptr = try sema.resolveInst(extra.lhs);
const start = try sema.resolveInst(extra.start);
- const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node };
- const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node };
- const end_src: LazySrcLoc = .{ .node_offset_slice_end = inst_data.src_node };
+ const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
+ const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
+ const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });
- return sema.analyzeSlice(block, src, array_ptr, start, .none, .none, .unneeded, ptr_src, start_src, end_src, false);
+ return sema.analyzeSlice(block, src, array_ptr, start, .none, .none, LazySrcLoc.unneeded, ptr_src, start_src, end_src, false);
}
fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -10942,11 +10858,11 @@ fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const array_ptr = try sema.resolveInst(extra.lhs);
const start = try sema.resolveInst(extra.start);
const end = try sema.resolveInst(extra.end);
- const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node };
- const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node };
- const end_src: LazySrcLoc = .{ .node_offset_slice_end = inst_data.src_node };
+ const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
+ const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
+ const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });
- return sema.analyzeSlice(block, src, array_ptr, start, end, .none, .unneeded, ptr_src, start_src, end_src, false);
+ return sema.analyzeSlice(block, src, array_ptr, start, end, .none, LazySrcLoc.unneeded, ptr_src, start_src, end_src, false);
}
fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -10955,15 +10871,15 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const sentinel_src: LazySrcLoc = .{ .node_offset_slice_sentinel = inst_data.src_node };
+ const sentinel_src = block.src(.{ .node_offset_slice_sentinel = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;
const array_ptr = try sema.resolveInst(extra.lhs);
const start = try sema.resolveInst(extra.start);
const end: Air.Inst.Ref = if (extra.end == .none) .none else try sema.resolveInst(extra.end);
const sentinel = try sema.resolveInst(extra.sentinel);
- const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node };
- const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node };
- const end_src: LazySrcLoc = .{ .node_offset_slice_end = inst_data.src_node };
+ const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
+ const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
+ const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });
return sema.analyzeSlice(block, src, array_ptr, start, end, sentinel, sentinel_src, ptr_src, start_src, end_src, false);
}
@@ -10979,13 +10895,13 @@ fn zirSliceLength(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const start = try sema.resolveInst(extra.start);
const len = try sema.resolveInst(extra.len);
const sentinel = if (extra.sentinel == .none) .none else try sema.resolveInst(extra.sentinel);
- const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node };
- const start_src: LazySrcLoc = .{ .node_offset_slice_start = extra.start_src_node_offset };
- const end_src: LazySrcLoc = .{ .node_offset_slice_end = inst_data.src_node };
+ const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
+ const start_src = block.src(.{ .node_offset_slice_start = extra.start_src_node_offset });
+ const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });
const sentinel_src: LazySrcLoc = if (sentinel == .none)
- .unneeded
+ LazySrcLoc.unneeded
else
- .{ .node_offset_slice_sentinel = inst_data.src_node };
+ block.src(.{ .node_offset_slice_sentinel = inst_data.src_node });
return sema.analyzeSlice(block, src, array_ptr, start, len, sentinel, sentinel_src, ptr_src, start_src, end_src, true);
}
@@ -11019,8 +10935,8 @@ const SwitchProngAnalysis = struct {
prong_type: enum { normal, special },
prong_body: []const Zir.Inst.Index,
capture: Zir.Inst.SwitchBlock.ProngInfo.Capture,
- /// Must use the `scalar_capture`, `special_capture`, or `multi_capture` union field.
- raw_capture_src: Module.SwitchProngSrc,
+ /// Must use the `switch_capture` field in `offset`.
+ capture_src: LazySrcLoc,
/// The set of all values which can reach this prong. May be undefined
/// if the prong is special or contains ranges.
case_vals: []const Air.Inst.Ref,
@@ -11038,7 +10954,7 @@ const SwitchProngAnalysis = struct {
);
if (has_tag_capture) {
- const tag_ref = try spa.analyzeTagCapture(child_block, raw_capture_src, inline_case_capture);
+ const tag_ref = try spa.analyzeTagCapture(child_block, capture_src, inline_case_capture);
sema.inst_map.putAssumeCapacity(spa.tag_capture_inst, tag_ref);
}
defer if (has_tag_capture) assert(sema.inst_map.remove(spa.tag_capture_inst));
@@ -11053,7 +10969,7 @@ const SwitchProngAnalysis = struct {
child_block,
capture == .by_ref,
prong_type == .special,
- raw_capture_src,
+ capture_src,
case_vals,
inline_case_capture,
);
@@ -11079,8 +10995,8 @@ const SwitchProngAnalysis = struct {
prong_type: enum { normal, special },
prong_body: []const Zir.Inst.Index,
capture: Zir.Inst.SwitchBlock.ProngInfo.Capture,
- /// Must use the `scalar`, `special`, or `multi_capture` union field.
- raw_capture_src: Module.SwitchProngSrc,
+ /// Must use the `switch_capture` field in `offset`.
+ capture_src: LazySrcLoc,
/// The set of all values which can reach this prong. May be undefined
/// if the prong is special or contains ranges.
case_vals: []const Air.Inst.Ref,
@@ -11094,7 +11010,7 @@ const SwitchProngAnalysis = struct {
const sema = spa.sema;
if (has_tag_capture) {
- const tag_ref = try spa.analyzeTagCapture(case_block, raw_capture_src, inline_case_capture);
+ const tag_ref = try spa.analyzeTagCapture(case_block, capture_src, inline_case_capture);
sema.inst_map.putAssumeCapacity(spa.tag_capture_inst, tag_ref);
}
defer if (has_tag_capture) assert(sema.inst_map.remove(spa.tag_capture_inst));
@@ -11109,7 +11025,7 @@ const SwitchProngAnalysis = struct {
case_block,
capture == .by_ref,
prong_type == .special,
- raw_capture_src,
+ capture_src,
case_vals,
inline_case_capture,
);
@@ -11130,23 +11046,18 @@ const SwitchProngAnalysis = struct {
fn analyzeTagCapture(
spa: SwitchProngAnalysis,
block: *Block,
- raw_capture_src: Module.SwitchProngSrc,
+ capture_src: LazySrcLoc,
inline_case_capture: Air.Inst.Ref,
) CompileError!Air.Inst.Ref {
const sema = spa.sema;
const mod = sema.mod;
const operand_ty = sema.typeOf(spa.operand);
if (operand_ty.zigTypeTag(mod) != .Union) {
- const zir_datas = sema.code.instructions.items(.data);
- const switch_node_offset = zir_datas[@intFromEnum(spa.switch_block_inst)].pl_node.src_node;
- const raw_tag_capture_src: Module.SwitchProngSrc = switch (raw_capture_src) {
- .scalar_capture => |i| .{ .scalar_tag_capture = i },
- .multi_capture => |i| .{ .multi_tag_capture = i },
- .special_capture => .special_tag_capture,
- else => unreachable,
+ const tag_capture_src: LazySrcLoc = .{
+ .base_node_inst = capture_src.base_node_inst,
+ .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture },
};
- const capture_src = raw_tag_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .none);
- return sema.fail(block, capture_src, "cannot capture tag of non-union type '{}'", .{
+ return sema.fail(block, tag_capture_src, "cannot capture tag of non-union type '{}'", .{
operand_ty.fmt(mod),
});
}
@@ -11159,7 +11070,7 @@ const SwitchProngAnalysis = struct {
block: *Block,
capture_byref: bool,
is_special_prong: bool,
- raw_capture_src: Module.SwitchProngSrc,
+ capture_src: LazySrcLoc,
case_vals: []const Air.Inst.Ref,
inline_case_capture: Air.Inst.Ref,
) CompileError!Air.Inst.Ref {
@@ -11172,10 +11083,10 @@ const SwitchProngAnalysis = struct {
const operand_ty = sema.typeOf(spa.operand);
const operand_ptr_ty = if (capture_byref) sema.typeOf(spa.operand_ptr) else undefined;
- const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_node_offset };
+ const operand_src = block.src(.{ .node_offset_switch_operand = switch_node_offset });
if (inline_case_capture != .none) {
- const item_val = sema.resolveConstDefinedValue(block, .unneeded, inline_case_capture, undefined) catch unreachable;
+ const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inline_case_capture, undefined) catch unreachable;
if (operand_ty.zigTypeTag(zcu) == .Union) {
const field_index: u32 = @intCast(operand_ty.unionTagFieldIndex(item_val, zcu).?);
const union_obj = zcu.typeToUnion(operand_ty).?;
@@ -11216,7 +11127,7 @@ const SwitchProngAnalysis = struct {
.ErrorSet => if (spa.else_error_ty) |ty| {
return sema.bitCast(block, ty, spa.operand, operand_src, null);
} else {
- try block.addUnreachable(operand_src, false);
+ try sema.analyzeUnreachable(block, operand_src, false);
return .unreachable_value;
},
else => return spa.operand,
@@ -11226,14 +11137,14 @@ const SwitchProngAnalysis = struct {
switch (operand_ty.zigTypeTag(zcu)) {
.Union => {
const union_obj = zcu.typeToUnion(operand_ty).?;
- const first_item_val = sema.resolveConstDefinedValue(block, .unneeded, case_vals[0], undefined) catch unreachable;
+ const first_item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable;
const first_field_index: u32 = zcu.unionTagFieldIndex(union_obj, first_item_val).?;
const first_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[first_field_index]);
const field_indices = try sema.arena.alloc(u32, case_vals.len);
for (case_vals, field_indices) |item, *field_idx| {
- const item_val = sema.resolveConstDefinedValue(block, .unneeded, item, undefined) catch unreachable;
+ const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
field_idx.* = zcu.unionTagFieldIndex(union_obj, item_val).?;
}
@@ -11253,27 +11164,22 @@ const SwitchProngAnalysis = struct {
}
const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);
- @memset(case_srcs, .unneeded);
-
- break :capture_ty sema.resolvePeerTypes(block, .unneeded, dummy_captures, .{ .override = case_srcs }) catch |err| switch (err) {
- error.NeededSourceLocation => {
- // This must be a multi-prong so this must be a `multi_capture` src
- const multi_idx = raw_capture_src.multi_capture;
- const src_decl_ptr = zcu.declPtr(block.src_decl);
- for (case_srcs, 0..) |*case_src, i| {
- const raw_case_src: Module.SwitchProngSrc = .{ .multi = .{ .prong = multi_idx, .item = @intCast(i) } };
- case_src.* = raw_case_src.resolve(zcu, src_decl_ptr, switch_node_offset, .none);
- }
- const capture_src = raw_capture_src.resolve(zcu, src_decl_ptr, switch_node_offset, .none);
- _ = sema.resolvePeerTypes(block, capture_src, dummy_captures, .{ .override = case_srcs }) catch |err1| switch (err1) {
- error.AnalysisFail => {
- const msg = sema.err orelse return error.AnalysisFail;
- try sema.reparentOwnedErrorMsg(block, capture_src, msg, "capture group with incompatible types", .{});
- return error.AnalysisFail;
- },
- else => |e| return e,
- };
- unreachable;
+ for (case_srcs, 0..) |*case_src, i| {
+ case_src.* = .{
+ .base_node_inst = capture_src.base_node_inst,
+ .offset = .{ .switch_case_item = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = capture_src.offset.switch_capture.case_idx,
+ .item_idx = .{ .kind = .single, .index = @intCast(i) },
+ } },
+ };
+ }
+
+ break :capture_ty sema.resolvePeerTypes(block, capture_src, dummy_captures, .{ .override = case_srcs }) catch |err| switch (err) {
+ error.AnalysisFail => {
+ const msg = sema.err orelse return error.AnalysisFail;
+ try sema.reparentOwnedErrorMsg(capture_src, msg, "capture group with incompatible types", .{});
+ return error.AnalysisFail;
},
else => |e| return e,
};
@@ -11301,28 +11207,23 @@ const SwitchProngAnalysis = struct {
dummy.* = try zcu.undefRef(field_ptr_ty);
}
const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);
- @memset(case_srcs, .unneeded);
-
- break :resolve sema.resolvePeerTypes(block, .unneeded, dummy_captures, .{ .override = case_srcs }) catch |err| switch (err) {
- error.NeededSourceLocation => {
- // This must be a multi-prong so this must be a `multi_capture` src
- const multi_idx = raw_capture_src.multi_capture;
- const src_decl_ptr = zcu.declPtr(block.src_decl);
- for (case_srcs, 0..) |*case_src, i| {
- const raw_case_src: Module.SwitchProngSrc = .{ .multi = .{ .prong = multi_idx, .item = @intCast(i) } };
- case_src.* = raw_case_src.resolve(zcu, src_decl_ptr, switch_node_offset, .none);
- }
- const capture_src = raw_capture_src.resolve(zcu, src_decl_ptr, switch_node_offset, .none);
- _ = sema.resolvePeerTypes(block, capture_src, dummy_captures, .{ .override = case_srcs }) catch |err1| switch (err1) {
- error.AnalysisFail => {
- const msg = sema.err orelse return error.AnalysisFail;
- try sema.errNote(block, capture_src, msg, "this coercion is only possible when capturing by value", .{});
- try sema.reparentOwnedErrorMsg(block, capture_src, msg, "capture group with incompatible types", .{});
- return error.AnalysisFail;
- },
- else => |e| return e,
- };
- unreachable;
+ for (case_srcs, 0..) |*case_src, i| {
+ case_src.* = .{
+ .base_node_inst = capture_src.base_node_inst,
+ .offset = .{ .switch_case_item = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = capture_src.offset.switch_capture.case_idx,
+ .item_idx = .{ .kind = .single, .index = @intCast(i) },
+ } },
+ };
+ }
+
+ break :resolve sema.resolvePeerTypes(block, capture_src, dummy_captures, .{ .override = case_srcs }) catch |err| switch (err) {
+ error.AnalysisFail => {
+ const msg = sema.err orelse return error.AnalysisFail;
+ try sema.errNote(capture_src, msg, "this coercion is only possible when capturing by value", .{});
+ try sema.reparentOwnedErrorMsg(capture_src, msg, "capture group with incompatible types", .{});
+ return error.AnalysisFail;
},
else => |e| return e,
};
@@ -11357,7 +11258,7 @@ const SwitchProngAnalysis = struct {
const first_non_imc = in_mem: {
for (field_indices, 0..) |field_idx, i| {
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
- if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), .unneeded, .unneeded)) {
+ if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded)) {
break :in_mem i;
}
}
@@ -11380,7 +11281,7 @@ const SwitchProngAnalysis = struct {
const next = first_non_imc + 1;
for (field_indices[next..], next..) |field_idx, i| {
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
- if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), .unneeded, .unneeded)) {
+ if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded)) {
in_mem_coercible.unset(i);
}
}
@@ -11409,20 +11310,19 @@ const SwitchProngAnalysis = struct {
var coerce_block = block.makeSubBlock();
defer coerce_block.instructions.deinit(sema.gpa);
+ const case_src: LazySrcLoc = .{
+ .base_node_inst = capture_src.base_node_inst,
+ .offset = .{ .switch_case_item = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = capture_src.offset.switch_capture.case_idx,
+ .item_idx = .{ .kind = .single, .index = @intCast(idx) },
+ } },
+ };
+
const field_idx = field_indices[idx];
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
const uncoerced = try coerce_block.addStructFieldVal(spa.operand, field_idx, field_ty);
- const coerced = sema.coerce(&coerce_block, capture_ty, uncoerced, .unneeded) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const multi_idx = raw_capture_src.multi_capture;
- const src_decl_ptr = zcu.declPtr(block.src_decl);
- const raw_case_src: Module.SwitchProngSrc = .{ .multi = .{ .prong = multi_idx, .item = @intCast(idx) } };
- const case_src = raw_case_src.resolve(zcu, src_decl_ptr, switch_node_offset, .none);
- _ = try sema.coerce(&coerce_block, capture_ty, uncoerced, case_src);
- unreachable;
- },
- else => |e| return e,
- };
+ const coerced = try sema.coerce(&coerce_block, capture_ty, uncoerced, case_src);
_ = try coerce_block.addBr(capture_block_inst, coerced);
try cases_extra.ensureUnusedCapacity(3 + coerce_block.instructions.items.len);
@@ -11476,7 +11376,6 @@ const SwitchProngAnalysis = struct {
},
.ErrorSet => {
if (capture_byref) {
- const capture_src = raw_capture_src.resolve(zcu, zcu.declPtr(block.src_decl), switch_node_offset, .none);
return sema.fail(
block,
capture_src,
@@ -11486,7 +11385,7 @@ const SwitchProngAnalysis = struct {
}
if (case_vals.len == 1) {
- const item_val = sema.resolveConstDefinedValue(block, .unneeded, case_vals[0], undefined) catch unreachable;
+ const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, case_vals[0], undefined) catch unreachable;
const item_ty = try zcu.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?);
return sema.bitCast(block, item_ty, spa.operand, operand_src, null);
}
@@ -11494,7 +11393,7 @@ const SwitchProngAnalysis = struct {
var names: InferredErrorSet.NameMap = .{};
try names.ensureUnusedCapacity(sema.arena, case_vals.len);
for (case_vals) |err| {
- const err_val = sema.resolveConstDefinedValue(block, .unneeded, err, undefined) catch unreachable;
+ const err_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, err, undefined) catch unreachable;
names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});
}
const error_ty = try zcu.errorSetFromUnsortedNames(names.keys());
@@ -11548,10 +11447,10 @@ fn switchCond(
try sema.resolveTypeFields(operand_ty);
const enum_ty = operand_ty.unionTagType(mod) orelse {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "switch on union with no attached enum", .{});
+ const msg = try sema.errMsg(src, "switch on union with no attached enum", .{});
errdefer msg.destroy(sema.gpa);
- if (operand_ty.declSrcLocOrNull(mod)) |union_src| {
- try mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{});
+ if (operand_ty.srcLocOrNull(mod)) |union_src| {
+ try sema.errNote(union_src, msg, "consider 'union(enum)' here", .{});
}
break :msg msg;
};
@@ -11575,7 +11474,7 @@ fn switchCond(
}
}
-const SwitchErrorSet = std.AutoHashMap(InternPool.NullTerminatedString, Module.SwitchProngSrc);
+const SwitchErrorSet = std.AutoHashMap(InternPool.NullTerminatedString, LazySrcLoc);
fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
@@ -11586,11 +11485,11 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const switch_src = block.nodeOffset(inst_data.src_node);
const switch_src_node_offset = inst_data.src_node;
- const switch_operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_src_node_offset };
- const else_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = switch_src_node_offset };
+ const switch_operand_src = block.src(.{ .node_offset_switch_operand = switch_src_node_offset });
+ const else_prong_src = block.src(.{ .node_offset_switch_special_prong = switch_src_node_offset });
const extra = sema.code.extraData(Zir.Inst.SwitchBlockErrUnion, inst_data.payload_index);
- const main_operand_src: LazySrcLoc = .{ .node_offset_if_cond = extra.data.main_src_node_offset };
- const main_src: LazySrcLoc = .{ .node_offset_main_token = extra.data.main_src_node_offset };
+ const main_operand_src = block.src(.{ .node_offset_if_cond = extra.data.main_src_node_offset });
+ const main_src = block.src(.{ .node_offset_main_token = extra.data.main_src_node_offset });
const raw_operand_val = try sema.resolveInst(extra.data.operand);
@@ -11710,6 +11609,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
.runtime_index = block.runtime_index,
.error_return_trace_index = block.error_return_trace_index,
.want_safety = block.want_safety,
+ .src_base_inst = block.src_base_inst,
};
const merges = &child_block.label.?.merges;
defer child_block.instructions.deinit(gpa);
@@ -11776,6 +11676,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
try sema.switchCond(block, switch_operand_src, spa.operand),
err_val,
operand_err_set_ty,
+ switch_src_node_offset,
.{
.body = else_case.body,
.end = else_case.end,
@@ -11817,7 +11718,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
var sub_block = child_block.makeSubBlock();
sub_block.runtime_loop = null;
- sub_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(main_operand_src, mod);
+ sub_block.runtime_cond = main_operand_src;
sub_block.runtime_index.increment();
sub_block.need_debug_scope = null; // this body is emitted regardless
defer sub_block.instructions.deinit(gpa);
@@ -11894,8 +11795,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const src_node_offset = inst_data.src_node;
- const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
- const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset };
+ const operand_src = block.src(.{ .node_offset_switch_operand = src_node_offset });
+ const special_prong_src = block.src(.{ .node_offset_switch_special_prong = src_node_offset });
const extra = sema.code.extraData(Zir.Inst.SwitchBlock, inst_data.payload_index);
const raw_operand_val: Air.Inst.Ref, const raw_operand_ptr: Air.Inst.Ref = blk: {
@@ -11962,7 +11863,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union;
// Duplicate checking variables later also used for `inline else`.
- var seen_enum_fields: []?Module.SwitchProngSrc = &.{};
+ var seen_enum_fields: []?LazySrcLoc = &.{};
var seen_errors = SwitchErrorSet.init(gpa);
var range_set = RangeSet.init(gpa, mod);
var true_count: u8 = 0;
@@ -11985,21 +11886,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
if (special_prong == .under and (!operand_ty.isNonexhaustiveEnum(mod) or union_originally)) {
const msg = msg: {
const msg = try sema.errMsg(
- block,
src,
"'_' prong only allowed when switching on non-exhaustive enums",
.{},
);
errdefer msg.destroy(gpa);
try sema.errNote(
- block,
special_prong_src,
msg,
"'_' prong here",
.{},
);
try sema.errNote(
- block,
src,
msg,
"consider using 'else'",
@@ -12014,7 +11912,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
switch (operand_ty.zigTypeTag(mod)) {
.Union => unreachable, // handled in `switchCond`
.Enum => {
- seen_enum_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount(mod));
+ seen_enum_fields = try gpa.alloc(?LazySrcLoc, operand_ty.enumFieldCount(mod));
empty_enum = seen_enum_fields.len == 0 and !operand_ty.isNonexhaustiveEnum(mod);
@memset(seen_enum_fields, null);
// `range_set` is used for non-exhaustive enum values that do not correspond to any tags.
@@ -12034,8 +11932,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
&range_set,
item_ref,
operand_ty,
- src_node_offset,
- .{ .scalar = scalar_i },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .scalar, .index = @intCast(scalar_i) },
+ .item_idx = .{ .kind = .single, .index = 0 },
+ } }),
));
}
}
@@ -12059,8 +11960,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
&range_set,
item_ref,
operand_ty,
- src_node_offset,
- .{ .multi = .{ .prong = multi_i, .item = @intCast(item_i) } },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ .item_idx = .{ .kind = .single, .index = @intCast(item_i) },
+ } }),
));
}
@@ -12081,7 +11985,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
} else if (!all_tags_handled) {
const msg = msg: {
const msg = try sema.errMsg(
- block,
src,
"switch must handle all possibilities",
.{},
@@ -12099,8 +12002,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
.{field_name.fmt(&mod.intern_pool)},
);
}
- try mod.errNoteNonLazy(
- operand_ty.declSrcLoc(mod),
+ try sema.errNote(
+ operand_ty.srcLoc(mod),
msg,
"enum '{}' declared here",
.{operand_ty.fmt(mod)},
@@ -12144,8 +12047,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
&range_set,
item_ref,
operand_ty,
- src_node_offset,
- .{ .scalar = scalar_i },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .scalar, .index = @intCast(scalar_i) },
+ .item_idx = .{ .kind = .single, .index = 0 },
+ } }),
));
}
}
@@ -12168,8 +12074,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
&range_set,
item_ref,
operand_ty,
- src_node_offset,
- .{ .multi = .{ .prong = multi_i, .item = @intCast(item_i) } },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ .item_idx = .{ .kind = .single, .index = @intCast(item_i) },
+ } }),
));
}
@@ -12187,8 +12096,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
item_first,
item_last,
operand_ty,
- src_node_offset,
- .{ .range = .{ .prong = multi_i, .item = range_i } },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ .item_idx = .{ .kind = .range, .index = @intCast(range_i) },
+ } }),
);
case_vals.appendAssumeCapacity(vals[0]);
case_vals.appendAssumeCapacity(vals[1]);
@@ -12239,8 +12151,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
&true_count,
&false_count,
item_ref,
- src_node_offset,
- .{ .scalar = scalar_i },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .scalar, .index = @intCast(scalar_i) },
+ .item_idx = .{ .kind = .single, .index = 0 },
+ } }),
));
}
}
@@ -12263,8 +12178,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
&true_count,
&false_count,
item_ref,
- src_node_offset,
- .{ .multi = .{ .prong = multi_i, .item = @intCast(item_i) } },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ .item_idx = .{ .kind = .single, .index = @intCast(item_i) },
+ } }),
));
}
@@ -12322,8 +12240,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
&seen_values,
item_ref,
operand_ty,
- src_node_offset,
- .{ .scalar = scalar_i },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .scalar, .index = @intCast(scalar_i) },
+ .item_idx = .{ .kind = .single, .index = 0 },
+ } }),
));
}
}
@@ -12346,8 +12267,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
&seen_values,
item_ref,
operand_ty,
- src_node_offset,
- .{ .multi = .{ .prong = multi_i, .item = @intCast(item_i) } },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ .item_idx = .{ .kind = .single, .index = @intCast(item_i) },
+ } }),
));
}
@@ -12417,6 +12341,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
.runtime_index = block.runtime_index,
.want_safety = block.want_safety,
.error_return_trace_index = block.error_return_trace_index,
+ .src_base_inst = block.src_base_inst,
};
const merges = &child_block.label.?.merges;
defer child_block.instructions.deinit(gpa);
@@ -12430,6 +12355,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
operand,
operand_val,
operand_ty,
+ src_node_offset,
special,
case_vals,
scalar_cases_len,
@@ -12462,7 +12388,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
.special,
special.body,
special.capture,
- .special_capture,
+ block.src(.{ .switch_capture = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = LazySrcLoc.Offset.SwitchCaseIndex.special,
+ } }),
undefined, // case_vals may be undefined for special prongs
.none,
false,
@@ -12529,9 +12458,9 @@ fn analyzeSwitchRuntimeBlock(
union_originally: bool,
maybe_union_ty: Type,
err_set: bool,
- src_node_offset: i32,
+ switch_node_offset: i32,
special_prong_src: LazySrcLoc,
- seen_enum_fields: []?Module.SwitchProngSrc,
+ seen_enum_fields: []?LazySrcLoc,
seen_errors: SwitchErrorSet,
range_set: RangeSet,
true_count: u8,
@@ -12552,7 +12481,7 @@ fn analyzeSwitchRuntimeBlock(
var case_block = child_block.makeSubBlock();
case_block.runtime_loop = null;
- case_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(operand_src, mod);
+ case_block.runtime_cond = operand_src;
case_block.runtime_index.increment();
case_block.need_debug_scope = null; // this body is emitted regardless
defer case_block.instructions.deinit(gpa);
@@ -12574,7 +12503,7 @@ fn analyzeSwitchRuntimeBlock(
// `item` is already guaranteed to be constant known.
const analyze_body = if (union_originally) blk: {
- const unresolved_item_val = sema.resolveConstDefinedValue(block, .unneeded, item, undefined) catch unreachable;
+ const unresolved_item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
const item_val = sema.resolveLazyValue(unresolved_item_val) catch unreachable;
const field_ty = maybe_union_ty.unionFieldType(item_val, mod).?;
break :blk field_ty.zigTypeTag(mod) != .NoReturn;
@@ -12588,7 +12517,10 @@ fn analyzeSwitchRuntimeBlock(
.normal,
body,
info.capture,
- .{ .scalar_capture = @intCast(scalar_i) },
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .scalar, .index = @intCast(scalar_i) },
+ } }),
&.{item},
if (info.is_inline) item else .none,
info.has_tag_capture,
@@ -12643,8 +12575,8 @@ fn analyzeSwitchRuntimeBlock(
const item_first_ref = range_items[0];
const item_last_ref = range_items[1];
- var item = sema.resolveConstDefinedValue(block, .unneeded, item_first_ref, undefined) catch unreachable;
- const item_last = sema.resolveConstDefinedValue(block, .unneeded, item_last_ref, undefined) catch unreachable;
+ var item = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_first_ref, undefined) catch unreachable;
+ const item_last = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item_last_ref, undefined) catch unreachable;
while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({
// Previous validation has resolved any possible lazy values.
@@ -12660,17 +12592,11 @@ fn analyzeSwitchRuntimeBlock(
case_block.instructions.shrinkRetainingCapacity(0);
case_block.error_return_trace_index = child_block.error_return_trace_index;
- if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const case_src = Module.SwitchProngSrc{
- .range = .{ .prong = multi_i, .item = range_i },
- };
- const decl = mod.declPtr(case_block.src_decl);
- try sema.emitBackwardBranch(block, case_src.resolve(mod, decl, src_node_offset, .none));
- unreachable;
- },
- else => return err,
- };
+ if (emit_bb) try sema.emitBackwardBranch(block, block.src(.{ .switch_case_item = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ .item_idx = .{ .kind = .range, .index = @intCast(range_i) },
+ } }));
emit_bb = true;
try spa.analyzeProngRuntime(
@@ -12678,7 +12604,10 @@ fn analyzeSwitchRuntimeBlock(
.normal,
body,
info.capture,
- .{ .multi_capture = multi_i },
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ } }),
undefined, // case_vals may be undefined for ranges
item_ref,
info.has_tag_capture,
@@ -12701,22 +12630,16 @@ fn analyzeSwitchRuntimeBlock(
case_block.error_return_trace_index = child_block.error_return_trace_index;
const analyze_body = if (union_originally) blk: {
- const item_val = sema.resolveConstDefinedValue(block, .unneeded, item, undefined) catch unreachable;
+ const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
const field_ty = maybe_union_ty.unionFieldType(item_val, mod).?;
break :blk field_ty.zigTypeTag(mod) != .NoReturn;
} else true;
- if (emit_bb) sema.emitBackwardBranch(block, .unneeded) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const case_src = Module.SwitchProngSrc{
- .multi = .{ .prong = multi_i, .item = @intCast(item_i) },
- };
- const decl = mod.declPtr(case_block.src_decl);
- try sema.emitBackwardBranch(block, case_src.resolve(mod, decl, src_node_offset, .none));
- unreachable;
- },
- else => return err,
- };
+ if (emit_bb) try sema.emitBackwardBranch(block, block.src(.{ .switch_case_item = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ .item_idx = .{ .kind = .single, .index = @intCast(item_i) },
+ } }));
emit_bb = true;
if (analyze_body) {
@@ -12725,7 +12648,10 @@ fn analyzeSwitchRuntimeBlock(
.normal,
body,
info.capture,
- .{ .multi_capture = multi_i },
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ } }),
&.{item},
item,
info.has_tag_capture,
@@ -12755,7 +12681,7 @@ fn analyzeSwitchRuntimeBlock(
const analyze_body = if (union_originally)
for (items) |item| {
- const item_val = sema.resolveConstDefinedValue(block, .unneeded, item, undefined) catch unreachable;
+ const item_val = sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
const field_ty = maybe_union_ty.unionFieldType(item_val, mod).?;
if (field_ty.zigTypeTag(mod) != .NoReturn) break true;
} else false
@@ -12772,7 +12698,10 @@ fn analyzeSwitchRuntimeBlock(
.normal,
body,
info.capture,
- .{ .multi_capture = multi_i },
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ } }),
items,
.none,
false,
@@ -12856,7 +12785,10 @@ fn analyzeSwitchRuntimeBlock(
.normal,
body,
info.capture,
- .{ .multi_capture = multi_i },
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ } }),
items,
.none,
false,
@@ -12921,7 +12853,10 @@ fn analyzeSwitchRuntimeBlock(
.special,
special.body,
special.capture,
- .special_capture,
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = LazySrcLoc.Offset.SwitchCaseIndex.special,
+ } }),
&.{item_ref},
item_ref,
special.has_tag_capture,
@@ -12966,7 +12901,10 @@ fn analyzeSwitchRuntimeBlock(
.special,
special.body,
special.capture,
- .special_capture,
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = LazySrcLoc.Offset.SwitchCaseIndex.special,
+ } }),
&.{item_ref},
item_ref,
special.has_tag_capture,
@@ -12997,7 +12935,10 @@ fn analyzeSwitchRuntimeBlock(
.special,
special.body,
special.capture,
- .special_capture,
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = LazySrcLoc.Offset.SwitchCaseIndex.special,
+ } }),
&.{item_ref},
item_ref,
special.has_tag_capture,
@@ -13025,7 +12966,10 @@ fn analyzeSwitchRuntimeBlock(
.special,
special.body,
special.capture,
- .special_capture,
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = LazySrcLoc.Offset.SwitchCaseIndex.special,
+ } }),
&.{.bool_true},
.bool_true,
special.has_tag_capture,
@@ -13051,7 +12995,10 @@ fn analyzeSwitchRuntimeBlock(
.special,
special.body,
special.capture,
- .special_capture,
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = LazySrcLoc.Offset.SwitchCaseIndex.special,
+ } }),
&.{.bool_false},
.bool_false,
special.has_tag_capture,
@@ -13101,7 +13048,10 @@ fn analyzeSwitchRuntimeBlock(
.special,
special.body,
special.capture,
- .special_capture,
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = LazySrcLoc.Offset.SwitchCaseIndex.special,
+ } }),
undefined, // case_vals may be undefined for special prongs
.none,
false,
@@ -13161,6 +13111,7 @@ fn resolveSwitchComptime(
cond_operand: Air.Inst.Ref,
operand_val: Value,
operand_ty: Type,
+ switch_node_offset: i32,
special: SpecialProng,
case_vals: std.ArrayListUnmanaged(Air.Inst.Ref),
scalar_cases_len: u32,
@@ -13181,7 +13132,7 @@ fn resolveSwitchComptime(
extra_index += info.body_len;
const item = case_vals.items[scalar_i];
- const item_val = sema.resolveConstDefinedValue(child_block, .unneeded, item, undefined) catch unreachable;
+ const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
if (operand_val.eql(item_val, operand_ty, sema.mod)) {
if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);
return spa.resolveProngComptime(
@@ -13189,7 +13140,10 @@ fn resolveSwitchComptime(
.normal,
body,
info.capture,
- .{ .scalar_capture = @intCast(scalar_i) },
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .scalar, .index = @intCast(scalar_i) },
+ } }),
&.{item},
if (info.is_inline) cond_operand else .none,
info.has_tag_capture,
@@ -13215,7 +13169,7 @@ fn resolveSwitchComptime(
for (items) |item| {
// Validation above ensured these will succeed.
- const item_val = sema.resolveConstDefinedValue(child_block, .unneeded, item, undefined) catch unreachable;
+ const item_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, item, undefined) catch unreachable;
if (operand_val.eql(item_val, operand_ty, sema.mod)) {
if (err_set) try sema.maybeErrorUnwrapComptime(child_block, body, cond_operand);
return spa.resolveProngComptime(
@@ -13223,7 +13177,10 @@ fn resolveSwitchComptime(
.normal,
body,
info.capture,
- .{ .multi_capture = @intCast(multi_i) },
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ } }),
items,
if (info.is_inline) cond_operand else .none,
info.has_tag_capture,
@@ -13239,8 +13196,8 @@ fn resolveSwitchComptime(
case_val_idx += 2;
// Validation above ensured these will succeed.
- const first_val = sema.resolveConstDefinedValue(child_block, .unneeded, range_items[0], undefined) catch unreachable;
- const last_val = sema.resolveConstDefinedValue(child_block, .unneeded, range_items[1], undefined) catch unreachable;
+ const first_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, range_items[0], undefined) catch unreachable;
+ const last_val = sema.resolveConstDefinedValue(child_block, LazySrcLoc.unneeded, range_items[1], undefined) catch unreachable;
if ((try sema.compareAll(resolved_operand_val, .gte, first_val, operand_ty)) and
(try sema.compareAll(resolved_operand_val, .lte, last_val, operand_ty)))
{
@@ -13250,7 +13207,10 @@ fn resolveSwitchComptime(
.normal,
body,
info.capture,
- .{ .multi_capture = @intCast(multi_i) },
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ } }),
undefined, // case_vals may be undefined for ranges
if (info.is_inline) cond_operand else .none,
info.has_tag_capture,
@@ -13272,7 +13232,10 @@ fn resolveSwitchComptime(
.special,
special.body,
special.capture,
- .special_capture,
+ child_block.src(.{ .switch_capture = .{
+ .switch_node_offset = switch_node_offset,
+ .case_idx = LazySrcLoc.Offset.SwitchCaseIndex.special,
+ } }),
undefined, // case_vals may be undefined for special prongs
if (special.is_inline) cond_operand else .none,
special.has_tag_capture,
@@ -13358,36 +13321,19 @@ fn resolveSwitchItemVal(
item_ref: Zir.Inst.Ref,
/// Coerce `item_ref` to this type.
coerce_ty: Type,
- switch_node_offset: i32,
- switch_prong_src: Module.SwitchProngSrc,
- range_expand: Module.SwitchProngSrc.RangeExpand,
+ item_src: LazySrcLoc,
) CompileError!ResolvedSwitchItem {
- const mod = sema.mod;
const uncoerced_item = try sema.resolveInst(item_ref);
// Constructing a LazySrcLoc is costly because we only have the switch AST node.
// Only if we know for sure we need to report a compile error do we resolve the
// full source locations.
- const item = sema.coerce(block, coerce_ty, uncoerced_item, .unneeded) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const src = switch_prong_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, range_expand);
- _ = try sema.coerce(block, coerce_ty, uncoerced_item, src);
- unreachable;
- },
- else => |e| return e,
- };
+ const item = try sema.coerce(block, coerce_ty, uncoerced_item, item_src);
- const maybe_lazy = sema.resolveConstDefinedValue(block, .unneeded, item, undefined) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const src = switch_prong_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, range_expand);
- _ = try sema.resolveConstDefinedValue(block, src, item, .{
- .needed_comptime_reason = "switch prong values must be comptime-known",
- });
- unreachable;
- },
- else => |e| return e,
- };
+ const maybe_lazy = try sema.resolveConstDefinedValue(block, item_src, item, .{
+ .needed_comptime_reason = "switch prong values must be comptime-known",
+ });
const val = try sema.resolveLazyValue(maybe_lazy);
const new_item = if (val.toIntern() != maybe_lazy.toIntern()) blk: {
@@ -13430,8 +13376,11 @@ fn validateErrSetSwitch(
seen_errors,
item_ref,
operand_ty,
- src_node_offset,
- .{ .scalar = scalar_i },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .scalar, .index = @intCast(scalar_i) },
+ .item_idx = .{ .kind = .single, .index = 0 },
+ } }),
));
}
}
@@ -13454,8 +13403,11 @@ fn validateErrSetSwitch(
seen_errors,
item_ref,
operand_ty,
- src_node_offset,
- .{ .multi = .{ .prong = multi_i, .item = @intCast(item_i) } },
+ block.src(.{ .switch_case_item = .{
+ .switch_node_offset = src_node_offset,
+ .case_idx = .{ .kind = .multi, .index = @intCast(multi_i) },
+ .item_idx = .{ .kind = .single, .index = @intCast(item_i) },
+ } }),
));
}
@@ -13484,7 +13436,6 @@ fn validateErrSetSwitch(
if (!seen_errors.contains(error_name) and !has_else) {
const msg = maybe_msg orelse blk: {
maybe_msg = try sema.errMsg(
- block,
src,
"switch must handle all possibilities",
.{},
@@ -13493,7 +13444,6 @@ fn validateErrSetSwitch(
};
try sema.errNote(
- block,
src,
msg,
"unhandled error value: 'error.{}'",
@@ -13571,18 +13521,24 @@ fn validateSwitchRange(
first_ref: Zir.Inst.Ref,
last_ref: Zir.Inst.Ref,
operand_ty: Type,
- src_node_offset: i32,
- switch_prong_src: Module.SwitchProngSrc,
+ item_src: LazySrcLoc,
) CompileError![2]Air.Inst.Ref {
const mod = sema.mod;
- const first = try sema.resolveSwitchItemVal(block, first_ref, operand_ty, src_node_offset, switch_prong_src, .first);
- const last = try sema.resolveSwitchItemVal(block, last_ref, operand_ty, src_node_offset, switch_prong_src, .last);
+ const first_src: LazySrcLoc = .{
+ .base_node_inst = item_src.base_node_inst,
+ .offset = .{ .switch_case_item_range_first = item_src.offset.switch_case_item },
+ };
+ const last_src: LazySrcLoc = .{
+ .base_node_inst = item_src.base_node_inst,
+ .offset = .{ .switch_case_item_range_last = item_src.offset.switch_case_item },
+ };
+ const first = try sema.resolveSwitchItemVal(block, first_ref, operand_ty, first_src);
+ const last = try sema.resolveSwitchItemVal(block, last_ref, operand_ty, last_src);
if (try Value.fromInterned(first.val).compareAll(.gt, Value.fromInterned(last.val), operand_ty, mod)) {
- const src = switch_prong_src.resolve(mod, mod.declPtr(block.src_decl), src_node_offset, .first);
- return sema.fail(block, src, "range start value is greater than the end value", .{});
+ return sema.fail(block, item_src, "range start value is greater than the end value", .{});
}
- const maybe_prev_src = try range_set.add(first.val, last.val, switch_prong_src);
- try sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset);
+ const maybe_prev_src = try range_set.add(first.val, last.val, item_src);
+ try sema.validateSwitchDupe(block, maybe_prev_src, item_src);
return .{ first.ref, last.ref };
}
@@ -13592,36 +13548,34 @@ fn validateSwitchItemInt(
range_set: *RangeSet,
item_ref: Zir.Inst.Ref,
operand_ty: Type,
- src_node_offset: i32,
- switch_prong_src: Module.SwitchProngSrc,
+ item_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
- const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, src_node_offset, switch_prong_src, .none);
- const maybe_prev_src = try range_set.add(item.val, item.val, switch_prong_src);
- try sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset);
+ const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);
+ const maybe_prev_src = try range_set.add(item.val, item.val, item_src);
+ try sema.validateSwitchDupe(block, maybe_prev_src, item_src);
return item.ref;
}
fn validateSwitchItemEnum(
sema: *Sema,
block: *Block,
- seen_fields: []?Module.SwitchProngSrc,
+ seen_fields: []?LazySrcLoc,
range_set: *RangeSet,
item_ref: Zir.Inst.Ref,
operand_ty: Type,
- src_node_offset: i32,
- switch_prong_src: Module.SwitchProngSrc,
+ item_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
const ip = &sema.mod.intern_pool;
- const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, src_node_offset, switch_prong_src, .none);
+ const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);
const int = ip.indexToKey(item.val).enum_tag.int;
const field_index = ip.loadEnumType(ip.typeOf(item.val)).tagValueIndex(ip, int) orelse {
- const maybe_prev_src = try range_set.add(int, int, switch_prong_src);
- try sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset);
+ const maybe_prev_src = try range_set.add(int, int, item_src);
+ try sema.validateSwitchDupe(block, maybe_prev_src, item_src);
return item.ref;
};
const maybe_prev_src = seen_fields[field_index];
- seen_fields[field_index] = switch_prong_src;
- try sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset);
+ seen_fields[field_index] = item_src;
+ try sema.validateSwitchDupe(block, maybe_prev_src, item_src);
return item.ref;
}
@@ -13631,50 +13585,41 @@ fn validateSwitchItemError(
seen_errors: *SwitchErrorSet,
item_ref: Zir.Inst.Ref,
operand_ty: Type,
- src_node_offset: i32,
- switch_prong_src: Module.SwitchProngSrc,
+ item_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
const ip = &sema.mod.intern_pool;
- const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, src_node_offset, switch_prong_src, .none);
+ const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);
const error_name = ip.indexToKey(item.val).err.name;
- const maybe_prev_src = if (try seen_errors.fetchPut(error_name, switch_prong_src)) |prev|
+ const maybe_prev_src = if (try seen_errors.fetchPut(error_name, item_src)) |prev|
prev.value
else
null;
- try sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset);
+ try sema.validateSwitchDupe(block, maybe_prev_src, item_src);
return item.ref;
}
fn validateSwitchDupe(
sema: *Sema,
block: *Block,
- maybe_prev_src: ?Module.SwitchProngSrc,
- switch_prong_src: Module.SwitchProngSrc,
- src_node_offset: i32,
+ maybe_prev_src: ?LazySrcLoc,
+ item_src: LazySrcLoc,
) CompileError!void {
- const prev_prong_src = maybe_prev_src orelse return;
- const mod = sema.mod;
- const block_src_decl = mod.declPtr(block.src_decl);
- const src = switch_prong_src.resolve(mod, block_src_decl, src_node_offset, .none);
- const prev_src = prev_prong_src.resolve(mod, block_src_decl, src_node_offset, .none);
- const msg = msg: {
+ const prev_item_src = maybe_prev_src orelse return;
+ return sema.failWithOwnedErrorMsg(block, msg: {
const msg = try sema.errMsg(
- block,
- src,
+ item_src,
"duplicate switch value",
.{},
);
errdefer msg.destroy(sema.gpa);
try sema.errNote(
- block,
- prev_src,
+ prev_item_src,
msg,
"previous value here",
.{},
);
break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ });
}
fn validateSwitchItemBool(
@@ -13683,25 +13628,21 @@ fn validateSwitchItemBool(
true_count: *u8,
false_count: *u8,
item_ref: Zir.Inst.Ref,
- src_node_offset: i32,
- switch_prong_src: Module.SwitchProngSrc,
+ item_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
- const mod = sema.mod;
- const item = try sema.resolveSwitchItemVal(block, item_ref, Type.bool, src_node_offset, switch_prong_src, .none);
+ const item = try sema.resolveSwitchItemVal(block, item_ref, Type.bool, item_src);
if (Value.fromInterned(item.val).toBool()) {
true_count.* += 1;
} else {
false_count.* += 1;
}
if (true_count.* > 1 or false_count.* > 1) {
- const block_src_decl = sema.mod.declPtr(block.src_decl);
- const src = switch_prong_src.resolve(mod, block_src_decl, src_node_offset, .none);
- return sema.fail(block, src, "duplicate switch value", .{});
+ return sema.fail(block, item_src, "duplicate switch value", .{});
}
return item.ref;
}
-const ValueSrcMap = std.AutoHashMapUnmanaged(InternPool.Index, Module.SwitchProngSrc);
+const ValueSrcMap = std.AutoHashMapUnmanaged(InternPool.Index, LazySrcLoc);
fn validateSwitchItemSparse(
sema: *Sema,
@@ -13709,12 +13650,11 @@ fn validateSwitchItemSparse(
seen_values: *ValueSrcMap,
item_ref: Zir.Inst.Ref,
operand_ty: Type,
- src_node_offset: i32,
- switch_prong_src: Module.SwitchProngSrc,
+ item_src: LazySrcLoc,
) CompileError!Air.Inst.Ref {
- const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, src_node_offset, switch_prong_src, .none);
- const kv = (try seen_values.fetchPut(sema.gpa, item.val, switch_prong_src)) orelse return item.ref;
- try sema.validateSwitchDupe(block, kv.value, switch_prong_src, src_node_offset);
+ const item = try sema.resolveSwitchItemVal(block, item_ref, operand_ty, item_src);
+ const kv = try seen_values.fetchPut(sema.gpa, item.val, item_src) orelse return item.ref;
+ try sema.validateSwitchDupe(block, kv.value, item_src);
unreachable;
}
@@ -13728,19 +13668,17 @@ fn validateSwitchNoRange(
if (ranges_len == 0)
return;
- const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
- const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset };
+ const operand_src = block.src(.{ .node_offset_switch_operand = src_node_offset });
+ const range_src = block.src(.{ .node_offset_switch_range = src_node_offset });
const msg = msg: {
const msg = try sema.errMsg(
- block,
operand_src,
"ranges not allowed when switching on type '{}'",
.{operand_ty.fmt(sema.mod)},
);
errdefer msg.destroy(sema.gpa);
try sema.errNote(
- block,
range_src,
msg,
"range here",
@@ -13867,8 +13805,8 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const ty = try sema.resolveType(block, ty_src, extra.lhs);
const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{
.needed_comptime_reason = "field name must be comptime-known",
@@ -13919,8 +13857,8 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
const decl_name = try sema.resolveConstStringIntern(block, rhs_src, extra.rhs, .{
.needed_comptime_reason = "decl name must be comptime-known",
@@ -13979,7 +13917,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const name = try sema.resolveConstString(block, operand_src, inst_data.operand, .{
.needed_comptime_reason = "file path name must be comptime-known",
});
@@ -13988,8 +13926,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
return sema.fail(block, operand_src, "file path name cannot be empty", .{});
}
- const src_loc = mod.declPtr(block.src_decl).toSrcLoc(operand_src, mod);
- const val = mod.embedFile(block.getFileScope(mod), name, src_loc) catch |err| switch (err) {
+ const val = mod.embedFile(block.getFileScope(mod), name, operand_src.upgrade(mod)) catch |err| switch (err) {
error.ImportOutsideModulePath => {
return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name});
},
@@ -14031,8 +13968,8 @@ fn zirShl(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -14201,8 +14138,8 @@ fn zirShr(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -14335,9 +14272,9 @@ fn zirBitwise(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -14390,7 +14327,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
+ const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
const operand = try sema.resolveInst(inst_data.operand);
const operand_type = sema.typeOf(operand);
@@ -14436,7 +14373,7 @@ fn analyzeTupleCat(
const mod = sema.mod;
const lhs_ty = sema.typeOf(lhs);
const rhs_ty = sema.typeOf(rhs);
- const src = LazySrcLoc.nodeOffset(src_node);
+ const src = block.nodeOffset(src_node);
const lhs_len = lhs_ty.structFieldCount(mod);
const rhs_len = rhs_ty.structFieldCount(mod);
@@ -14463,10 +14400,10 @@ fn analyzeTupleCat(
types[i] = lhs_ty.structFieldType(i, mod).toIntern();
const default_val = lhs_ty.structFieldDefaultValue(i, mod);
values[i] = default_val.toIntern();
- const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{
+ const operand_src = block.src(.{ .array_cat_lhs = .{
.array_cat_offset = src_node,
.elem_index = i,
- } };
+ } });
if (default_val.toIntern() == .unreachable_value) {
runtime_src = operand_src;
values[i] = .none;
@@ -14477,10 +14414,10 @@ fn analyzeTupleCat(
types[i + lhs_len] = rhs_ty.structFieldType(i, mod).toIntern();
const default_val = rhs_ty.structFieldDefaultValue(i, mod);
values[i + lhs_len] = default_val.toIntern();
- const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{
+ const operand_src = block.src(.{ .array_cat_rhs = .{
.array_cat_offset = src_node,
.elem_index = i,
- } };
+ } });
if (default_val.toIntern() == .unreachable_value) {
runtime_src = operand_src;
values[i + lhs_len] = .none;
@@ -14508,18 +14445,18 @@ fn analyzeTupleCat(
const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len);
var i: u32 = 0;
while (i < lhs_len) : (i += 1) {
- const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{
+ const operand_src = block.src(.{ .array_cat_lhs = .{
.array_cat_offset = src_node,
.elem_index = i,
- } };
+ } });
element_refs[i] = try sema.tupleFieldValByIndex(block, operand_src, lhs, i, lhs_ty);
}
i = 0;
while (i < rhs_len) : (i += 1) {
- const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{
+ const operand_src = block.src(.{ .array_cat_rhs = .{
.array_cat_offset = src_node,
.elem_index = i,
- } };
+ } });
element_refs[i + lhs_len] =
try sema.tupleFieldValByIndex(block, operand_src, rhs, i, rhs_ty);
}
@@ -14546,8 +14483,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
return sema.analyzeTupleCat(block, inst_data.src_node, lhs, rhs);
}
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, rhs_ty) orelse lhs_info: {
if (lhs_is_tuple) break :lhs_info @as(Type.ArrayInfo, undefined);
@@ -14659,10 +14596,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, mod) else Value.@"unreachable";
const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(mod, lhs_elem_i) else elem_default_val;
const elem_val_inst = Air.internedToRef(elem_val.toIntern());
- const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{
+ const operand_src = block.src(.{ .array_cat_lhs = .{
.array_cat_offset = inst_data.src_node,
.elem_index = elem_i,
- } };
+ } });
const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
element_vals[elem_i] = coerced_elem_val.toIntern();
@@ -14672,10 +14609,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, mod) else Value.@"unreachable";
const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(mod, rhs_elem_i) else elem_default_val;
const elem_val_inst = Air.internedToRef(elem_val.toIntern());
- const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{
+ const operand_src = block.src(.{ .array_cat_rhs = .{
.array_cat_offset = inst_data.src_node,
.elem_index = @intCast(rhs_elem_i),
- } };
+ } });
const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
element_vals[elem_i] = coerced_elem_val.toIntern();
@@ -14704,10 +14641,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
while (elem_i < lhs_len) : (elem_i += 1) {
const elem_index = try mod.intRef(Type.usize, elem_i);
const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
- const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{
+ const operand_src = block.src(.{ .array_cat_lhs = .{
.array_cat_offset = inst_data.src_node,
.elem_index = elem_i,
- } };
+ } });
const init = try sema.elemVal(block, operand_src, lhs, elem_index, src, true);
try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store);
}
@@ -14716,10 +14653,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const elem_index = try mod.intRef(Type.usize, elem_i);
const rhs_index = try mod.intRef(Type.usize, rhs_elem_i);
const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
- const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{
+ const operand_src = block.src(.{ .array_cat_rhs = .{
.array_cat_offset = inst_data.src_node,
.elem_index = @intCast(rhs_elem_i),
- } };
+ } });
const init = try sema.elemVal(block, operand_src, rhs, rhs_index, src, true);
try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store);
}
@@ -14738,20 +14675,20 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
var elem_i: u32 = 0;
while (elem_i < lhs_len) : (elem_i += 1) {
const index = try mod.intRef(Type.usize, elem_i);
- const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{
+ const operand_src = block.src(.{ .array_cat_lhs = .{
.array_cat_offset = inst_data.src_node,
.elem_index = elem_i,
- } };
+ } });
const init = try sema.elemVal(block, operand_src, lhs, index, src, true);
element_refs[elem_i] = try sema.coerce(block, resolved_elem_ty, init, operand_src);
}
while (elem_i < result_len) : (elem_i += 1) {
const rhs_elem_i = elem_i - lhs_len;
const index = try mod.intRef(Type.usize, rhs_elem_i);
- const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{
+ const operand_src = block.src(.{ .array_cat_rhs = .{
.array_cat_offset = inst_data.src_node,
.elem_index = @intCast(rhs_elem_i),
- } };
+ } });
const init = try sema.elemVal(block, operand_src, rhs, index, src, true);
element_refs[elem_i] = try sema.coerce(block, resolved_elem_ty, init, operand_src);
}
@@ -14813,8 +14750,8 @@ fn analyzeTupleMul(
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const operand_ty = sema.typeOf(operand);
- const src = LazySrcLoc.nodeOffset(src_node);
- const len_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node };
+ const src = block.nodeOffset(src_node);
+ const len_src = block.src(.{ .node_offset_bin_rhs = src_node });
const tuple_len = operand_ty.structFieldCount(mod);
const final_len = std.math.mul(usize, tuple_len, factor) catch
@@ -14831,10 +14768,10 @@ fn analyzeTupleMul(
for (0..tuple_len) |i| {
types[i] = operand_ty.structFieldType(i, mod).toIntern();
values[i] = operand_ty.structFieldDefaultValue(i, mod).toIntern();
- const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{
+ const operand_src = block.src(.{ .array_cat_lhs = .{
.array_cat_offset = src_node,
.elem_index = @intCast(i),
- } };
+ } });
if (values[i] == .unreachable_value) {
runtime_src = operand_src;
values[i] = .none; // TODO don't treat unreachable_value as special
@@ -14866,10 +14803,10 @@ fn analyzeTupleMul(
const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len);
var i: u32 = 0;
while (i < tuple_len) : (i += 1) {
- const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{
+ const operand_src = block.src(.{ .array_cat_lhs = .{
.array_cat_offset = src_node,
.elem_index = i,
- } };
+ } });
element_refs[i] = try sema.tupleFieldValByIndex(block, operand_src, operand, @intCast(i), operand_ty);
}
i = 1;
@@ -14890,9 +14827,9 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const uncoerced_lhs = try sema.resolveInst(extra.lhs);
const uncoerced_lhs_ty = sema.typeOf(uncoerced_lhs);
const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const operator_src: LazySrcLoc = .{ .node_offset_main_token = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const operator_src = block.src(.{ .node_offset_main_token = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const lhs, const lhs_ty = coerced_lhs: {
// If we have a result type, we might be able to do this more efficiently
@@ -14941,11 +14878,11 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
// Analyze the lhs first, to catch the case that someone tried to do exponentiation
const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs, lhs_ty) orelse {
const msg = msg: {
- const msg = try sema.errMsg(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)});
+ const msg = try sema.errMsg(lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
switch (lhs_ty.zigTypeTag(mod)) {
.Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {
- try sema.errNote(block, operator_src, msg, "this operator multiplies arrays; use std.math.pow for exponentiation", .{});
+ try sema.errNote(operator_src, msg, "this operator multiplies arrays; use std.math.pow for exponentiation", .{});
},
else => {},
}
@@ -15061,7 +14998,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const lhs_src = src;
- const rhs_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
+ const rhs_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
const rhs = try sema.resolveInst(inst_data.operand);
const rhs_ty = sema.typeOf(rhs);
@@ -15093,7 +15030,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
const lhs_src = src;
- const rhs_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
+ const rhs_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
const rhs = try sema.resolveInst(inst_data.operand);
const rhs_ty = sema.typeOf(rhs);
@@ -15119,9 +15056,9 @@ fn zirArithmetic(
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -15132,9 +15069,9 @@ fn zirArithmetic(
fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -15297,9 +15234,9 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -15462,9 +15399,9 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -15572,9 +15509,9 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -15813,9 +15750,9 @@ fn airTag(block: *Block, is_int: bool, normal: Air.Inst.Tag, optimized: Air.Inst
fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -15997,9 +15934,9 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr
fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -16092,9 +16029,9 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -16194,10 +16131,10 @@ fn zirOverflowArithmetic(
defer tracy.end();
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
+ const src = block.nodeOffset(extra.node);
- const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
+ const lhs_src = block.builtinCallArgSrc(extra.node, 0);
+ const rhs_src = block.builtinCallArgSrc(extra.node, 1);
const uncasted_lhs = try sema.resolveInst(extra.lhs);
const uncasted_rhs = try sema.resolveInst(extra.rhs);
@@ -17025,8 +16962,8 @@ fn zirAsm(
defer tracy.end();
const extra = sema.code.extraData(Zir.Inst.Asm, extended.operand);
- const src = LazySrcLoc.nodeOffset(extra.data.src_node);
- const ret_ty_src: LazySrcLoc = .{ .node_offset_asm_ret_ty = extra.data.src_node };
+ const src = block.nodeOffset(extra.data.src_node);
+ const ret_ty_src = block.src(.{ .node_offset_asm_ret_ty = extra.data.src_node });
const outputs_len: u5 = @truncate(extended.small);
const inputs_len: u5 = @truncate(extended.small >> 5);
const clobbers_len: u5 = @truncate(extended.small >> 10);
@@ -17200,8 +17137,8 @@ fn zirCmpEq(
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
@@ -17280,9 +17217,9 @@ fn analyzeCmpUnionTag(
try sema.resolveTypeFields(union_ty);
const union_tag_ty = union_ty.unionTagType(mod) orelse {
const msg = msg: {
- const msg = try sema.errMsg(block, un_src, "comparison of union and enum literal is only valid for tagged union types", .{});
+ const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});
errdefer msg.destroy(sema.gpa);
- try mod.errNoteNonLazy(union_ty.declSrcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(mod)});
+ try sema.errNote(union_ty.srcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(mod)});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -17316,8 +17253,8 @@ fn zirCmp(
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
return sema.analyzeCmp(block, src, lhs, rhs, op, lhs_src, rhs_src, false);
@@ -17459,7 +17396,7 @@ fn runtimeBoolCmp(
fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const ty = try sema.resolveType(block, operand_src, inst_data.operand);
switch (ty.zigTypeTag(mod)) {
.Fn,
@@ -17502,7 +17439,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand);
switch (operand_ty.zigTypeTag(mod)) {
.Fn,
@@ -17546,7 +17483,7 @@ fn zirThis(
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const this_decl_index = mod.namespacePtr(block.namespace).decl_index;
- const src = LazySrcLoc.nodeOffset(@bitCast(extended.operand));
+ const src = block.nodeOffset(@bitCast(extended.operand));
return sema.analyzeDeclVal(block, src, this_decl_index);
}
@@ -17556,7 +17493,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
const captures = mod.namespacePtr(block.namespace).getType(mod).getCaptures(mod);
const src_node: i32 = @bitCast(extended.operand);
- const src = LazySrcLoc.nodeOffset(src_node);
+ const src = block.nodeOffset(src_node);
const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) {
.@"comptime" => |index| return Air.internedToRef(index),
@@ -17570,7 +17507,8 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
if (!block.is_typeof and sema.func_index == .none) {
const msg = msg: {
const name = name: {
- const file = sema.owner_decl.getFileScope(mod);
+ // TODO: we should probably store this name in the ZIR to avoid this complexity.
+ const file, const src_base_node = Module.LazySrcLoc.resolveBaseNode(block.src_base_inst, mod);
const tree = file.getTree(sema.gpa) catch |err| {
// In this case we emit a warning + a less precise source location.
log.warn("unable to load {s}: {s}", .{
@@ -17578,15 +17516,15 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
});
break :name null;
};
- const node = sema.owner_decl.relativeToNodeIndex(src_node);
+ const node: std.zig.Ast.Node.Index = @bitCast(src_node + @as(i32, @bitCast(src_base_node)));
const token = tree.nodes.items(.main_token)[node];
break :name tree.tokenSlice(token);
};
const msg = if (name) |some|
- try sema.errMsg(block, src, "'{s}' not accessible outside function scope", .{some})
+ try sema.errMsg(src, "'{s}' not accessible outside function scope", .{some})
else
- try sema.errMsg(block, src, "variable not accessible outside function scope", .{});
+ try sema.errMsg(src, "variable not accessible outside function scope", .{});
errdefer msg.destroy(sema.gpa);
// TODO add "declared here" note
@@ -17598,7 +17536,7 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
if (!block.is_typeof and !block.is_comptime and sema.func_index != .none) {
const msg = msg: {
const name = name: {
- const file = sema.owner_decl.getFileScope(mod);
+ const file, const src_base_node = Module.LazySrcLoc.resolveBaseNode(block.src_base_inst, mod);
const tree = file.getTree(sema.gpa) catch |err| {
// In this case we emit a warning + a less precise source location.
log.warn("unable to load {s}: {s}", .{
@@ -17606,18 +17544,18 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
});
break :name null;
};
- const node = sema.owner_decl.relativeToNodeIndex(src_node);
+ const node: std.zig.Ast.Node.Index = @bitCast(src_node + @as(i32, @bitCast(src_base_node)));
const token = tree.nodes.items(.main_token)[node];
break :name tree.tokenSlice(token);
};
const msg = if (name) |some|
- try sema.errMsg(block, src, "'{s}' not accessible from inner function", .{some})
+ try sema.errMsg(src, "'{s}' not accessible from inner function", .{some})
else
- try sema.errMsg(block, src, "variable not accessible from inner function", .{});
+ try sema.errMsg(src, "variable not accessible from inner function", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, LazySrcLoc.nodeOffset(0), msg, "crossed function definition here", .{});
+ try sema.errNote(block.nodeOffset(0), msg, "crossed function definition here", .{});
// TODO add "declared here" note
break :msg msg;
@@ -17649,7 +17587,7 @@ fn zirFrameAddress(
block: *Block,
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
- const src = LazySrcLoc.nodeOffset(@bitCast(extended.operand));
+ const src = block.nodeOffset(@bitCast(extended.operand));
try sema.requireRuntimeBlock(block, src, null);
return try block.addNoOp(.frame_addr);
}
@@ -18913,6 +18851,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
.is_typeof = true,
.want_safety = false,
.error_return_trace_index = block.error_return_trace_index,
+ .src_base_inst = block.src_base_inst,
};
defer child_block.instructions.deinit(sema.gpa);
@@ -18977,7 +18916,7 @@ fn zirTypeofPeer(
defer tracy.end();
const extra = sema.code.extraData(Zir.Inst.TypeOfPeer, extended.operand);
- const src = LazySrcLoc.nodeOffset(extra.data.src_node);
+ const src = block.nodeOffset(extra.data.src_node);
const body = sema.code.bodySlice(extra.data.body_index, extra.data.body_len);
var child_block: Block = .{
@@ -18992,6 +18931,7 @@ fn zirTypeofPeer(
.runtime_cond = block.runtime_cond,
.runtime_loop = block.runtime_loop,
.runtime_index = block.runtime_index,
+ .src_base_inst = block.src_base_inst,
};
defer child_block.instructions.deinit(sema.gpa);
// Ignore the result, we only care about the instructions in `args`.
@@ -19017,7 +18957,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node };
+ const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
const uncasted_operand = try sema.resolveInst(inst_data.operand);
const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src);
@@ -19048,8 +18988,8 @@ fn zirBoolBr(
const uncoerced_lhs = try sema.resolveInst(extra.data.lhs);
const body = sema.code.bodySlice(extra.end, extra.data.body_len);
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const lhs_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = parent_block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const lhs = try sema.coerce(parent_block, Type.bool, uncoerced_lhs, lhs_src);
@@ -19080,7 +19020,7 @@ fn zirBoolBr(
var child_block = parent_block.makeSubBlock();
child_block.runtime_loop = null;
- child_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(lhs_src, mod);
+ child_block.runtime_cond = lhs_src;
child_block.runtime_index.increment();
defer child_block.instructions.deinit(gpa);
@@ -19253,7 +19193,7 @@ fn zirCondbr(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
+ const cond_src = parent_block.src(.{ .node_offset_if_cond = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index);
const then_body = sema.code.bodySlice(extra.end, extra.data.then_body_len);
@@ -19276,7 +19216,7 @@ fn zirCondbr(
// instructions array in between using it for the then block and else block.
var sub_block = parent_block.makeSubBlock();
sub_block.runtime_loop = null;
- sub_block.runtime_cond = mod.declPtr(parent_block.src_decl).toSrcLoc(cond_src, mod);
+ sub_block.runtime_cond = cond_src;
sub_block.runtime_index.increment();
sub_block.need_debug_scope = null; // this body is emitted regardless
defer sub_block.instructions.deinit(gpa);
@@ -19321,7 +19261,7 @@ fn zirCondbr(
fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = parent_block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
+ const operand_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
const body = sema.code.bodySlice(extra.end, extra.data.body_len);
const err_union = try sema.resolveInst(extra.data.operand);
@@ -19368,7 +19308,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = parent_block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
+ const operand_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
const body = sema.code.bodySlice(extra.end, extra.data.body_len);
const operand = try sema.resolveInst(extra.data.operand);
@@ -19464,6 +19404,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
.label = &labeled_block.label,
.inlining = block.inlining,
.is_comptime = block.is_comptime,
+ .src_base_inst = block.src_base_inst,
},
};
sema.post_hoc_blocks.putAssumeCapacityNoClobber(new_block_inst, labeled_block);
@@ -19498,11 +19439,11 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
return sema.fail(block, src, "reached unreachable code", .{});
}
// TODO Add compile error for @optimizeFor occurring too late in a scope.
- block.addUnreachable(src, true) catch |err| switch (err) {
+ sema.analyzeUnreachable(block, src, true) catch |err| switch (err) {
error.AnalysisFail => {
const msg = sema.err orelse return err;
if (!mem.eql(u8, msg.msg, "runtime safety check not allowed in naked function")) return err;
- try sema.errNote(block, src, msg, "the end of a naked function is implicitly unreachable", .{});
+ try sema.errNote(src, msg, "the end of a naked function is implicitly unreachable", .{});
return err;
},
else => |e| return e,
@@ -19549,31 +19490,31 @@ fn zirRetImplicit(
// Calling a safety function from a naked function would not be legal.
_ = try block.addNoOp(.trap);
} else {
- try block.addUnreachable(r_brace_src, false);
+ try sema.analyzeUnreachable(block, r_brace_src, false);
}
return;
}
const operand = try sema.resolveInst(inst_data.operand);
- const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
+ const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = 0 });
const base_tag = sema.fn_ret_ty.baseZigTypeTag(mod);
if (base_tag == .NoReturn) {
const msg = msg: {
- const msg = try sema.errMsg(block, ret_ty_src, "function declared '{}' implicitly returns", .{
+ const msg = try sema.errMsg(ret_ty_src, "function declared '{}' implicitly returns", .{
sema.fn_ret_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});
+ try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
} else if (base_tag != .Void) {
const msg = msg: {
- const msg = try sema.errMsg(block, ret_ty_src, "function with non-void return type '{}' implicitly returns", .{
+ const msg = try sema.errMsg(ret_ty_src, "function with non-void return type '{}' implicitly returns", .{
sema.fn_ret_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});
+ try sema.errNote(r_brace_src, msg, "control flow reaches end of body here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -19590,7 +19531,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
const operand = try sema.resolveInst(inst_data.operand);
const src = block.nodeOffset(inst_data.src_node);
- return sema.analyzeRet(block, operand, src, .{ .node_offset_return_operand = inst_data.src_node });
+ return sema.analyzeRet(block, operand, src, block.src(.{ .node_offset_return_operand = inst_data.src_node }));
}
fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
@@ -19603,7 +19544,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
if (block.is_comptime or block.inlining != null or sema.func_is_naked) {
const operand = try sema.analyzeLoad(block, src, ret_ptr, src);
- return sema.analyzeRet(block, operand, src, .{ .node_offset_return_operand = inst_data.src_node });
+ return sema.analyzeRet(block, operand, src, block.src(.{ .node_offset_return_operand = inst_data.src_node }));
}
if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
@@ -19816,9 +19757,7 @@ fn analyzeRet(
inlining.comptime_result = operand;
if (sema.fn_ret_ty.isError(mod) and ret_val.getErrorName(mod) != .none) {
- const src_decl = mod.declPtr(block.src_decl);
- const src_loc = src_decl.toSrcLoc(src, mod);
- try sema.comptime_err_ret_trace.append(src_loc);
+ try sema.comptime_err_ret_trace.append(src);
}
return error.ComptimeReturn;
}
@@ -19832,10 +19771,10 @@ fn analyzeRet(
return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{});
} else if (sema.func_is_naked) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "cannot return from naked function", .{});
+ const msg = try sema.errMsg(src, "cannot return from naked function", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "can only return using assembly", .{});
+ try sema.errNote(src, msg, "can only return using assembly", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -19871,18 +19810,18 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].ptr_type;
const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
- const elem_ty_src: LazySrcLoc = .{ .node_offset_ptr_elem = extra.data.src_node };
- const sentinel_src: LazySrcLoc = .{ .node_offset_ptr_sentinel = extra.data.src_node };
- const align_src: LazySrcLoc = .{ .node_offset_ptr_align = extra.data.src_node };
- const addrspace_src: LazySrcLoc = .{ .node_offset_ptr_addrspace = extra.data.src_node };
- const bitoffset_src: LazySrcLoc = .{ .node_offset_ptr_bitoffset = extra.data.src_node };
- const hostsize_src: LazySrcLoc = .{ .node_offset_ptr_hostsize = extra.data.src_node };
+ const elem_ty_src = block.src(.{ .node_offset_ptr_elem = extra.data.src_node });
+ const sentinel_src = block.src(.{ .node_offset_ptr_sentinel = extra.data.src_node });
+ const align_src = block.src(.{ .node_offset_ptr_align = extra.data.src_node });
+ const addrspace_src = block.src(.{ .node_offset_ptr_addrspace = extra.data.src_node });
+ const bitoffset_src = block.src(.{ .node_offset_ptr_bitoffset = extra.data.src_node });
+ const hostsize_src = block.src(.{ .node_offset_ptr_hostsize = extra.data.src_node });
const elem_ty = blk: {
const air_inst = try sema.resolveInst(extra.data.elem_type);
const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {
if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(mod)) {
- try sema.errNote(block, elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
+ try sema.errNote(elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
}
return err;
};
@@ -19974,11 +19913,10 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
} else if (inst_data.size == .C) {
if (!try sema.validateExternType(elem_ty, .other)) {
const msg = msg: {
- const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)});
+ const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(elem_ty_src, mod), elem_ty, .other);
+ try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);
try sema.addDeclaredHereNote(msg, elem_ty);
break :msg msg;
@@ -19992,10 +19930,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, elem_ty_src, "bit-pointer cannot refer to value of type '{}'", .{elem_ty.fmt(mod)});
+ const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{}'", .{elem_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotPacked(msg, src_decl.toSrcLoc(elem_ty_src, mod), elem_ty);
+ try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty);
break :msg msg;
});
}
@@ -20025,7 +19962,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const ty_src: LazySrcLoc = .{ .node_offset_init_ty = inst_data.src_node };
+ const ty_src = block.src(.{ .node_offset_init_ty = inst_data.src_node });
const obj_ty = try sema.resolveType(block, ty_src, inst_data.operand);
const mod = sema.mod;
@@ -20119,9 +20056,9 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com
fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const field_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
- const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
+ const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
+ const init_src = block.builtinCallArgSrc(inst_data.src_node, 2);
const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
if (union_ty.zigTypeTag(sema.mod) != .Union) {
@@ -20215,7 +20152,7 @@ fn zirStructInit(
extra_index = item.end;
const field_type_data = zir_datas[@intFromEnum(item.data.field_type)].pl_node;
- const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };
+ const field_src = block.src(.{ .node_offset_initializer = field_type_data.src_node });
const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
const field_name = try ip.getOrPutString(
gpa,
@@ -20256,7 +20193,7 @@ fn zirStructInit(
const item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end);
const field_type_data = zir_datas[@intFromEnum(item.data.field_type)].pl_node;
- const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };
+ const field_src = block.src(.{ .node_offset_initializer = field_type_data.src_node });
const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
const field_name = try ip.getOrPutString(
gpa,
@@ -20270,7 +20207,7 @@ fn zirStructInit(
if (field_ty.zigTypeTag(mod) == .NoReturn) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
+ const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{});
errdefer msg.destroy(sema.gpa);
try sema.addFieldErrNote(resolved_ty, field_index, msg, "field '{}' declared here", .{
@@ -20348,16 +20285,12 @@ fn finishStructInit(
for (0..anon_struct.types.len) |i| {
if (field_inits[i] != .none) {
// Coerce the init value to the field type.
+ const field_src = block.src(.{ .init_elem = .{
+ .init_node_offset = init_src.offset.node_offset.x,
+ .elem_index = @intCast(i),
+ } });
const field_ty = Type.fromInterned(anon_struct.types.get(ip)[i]);
- field_inits[i] = sema.coerce(block, field_ty, field_inits[i], .unneeded) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const decl = mod.declPtr(block.src_decl);
- const field_src = mod.initSrc(init_src.node_offset.x, decl, i);
- _ = try sema.coerce(block, field_ty, field_inits[i], field_src);
- unreachable;
- },
- else => |e| return e,
- };
+ field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src);
continue;
}
@@ -20367,18 +20300,18 @@ fn finishStructInit(
if (anon_struct.names.len == 0) {
const template = "missing tuple field with index {d}";
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, .{i});
+ try sema.errNote(init_src, msg, template, .{i});
} else {
- root_msg = try sema.errMsg(block, init_src, template, .{i});
+ root_msg = try sema.errMsg(init_src, template, .{i});
}
} else {
const field_name = anon_struct.names.get(ip)[i];
const template = "missing struct field: {}";
const args = .{field_name.fmt(ip)};
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, args);
+ try sema.errNote(init_src, msg, template, args);
} else {
- root_msg = try sema.errMsg(block, init_src, template, args);
+ root_msg = try sema.errMsg(init_src, template, args);
}
}
} else {
@@ -20391,16 +20324,12 @@ fn finishStructInit(
for (0..struct_type.field_types.len) |i| {
if (field_inits[i] != .none) {
// Coerce the init value to the field type.
+ const field_src = block.src(.{ .init_elem = .{
+ .init_node_offset = init_src.offset.node_offset.x,
+ .elem_index = @intCast(i),
+ } });
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
- field_inits[i] = sema.coerce(block, field_ty, field_inits[i], init_src) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const decl = mod.declPtr(block.src_decl);
- const field_src = mod.initSrc(init_src.node_offset.x, decl, i);
- _ = try sema.coerce(block, field_ty, field_inits[i], field_src);
- unreachable;
- },
- else => |e| return e,
- };
+ field_inits[i] = try sema.coerce(block, field_ty, field_inits[i], field_src);
continue;
}
@@ -20413,16 +20342,16 @@ fn finishStructInit(
const template = "missing struct field: {}";
const args = .{field_name.fmt(ip)};
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, args);
+ try sema.errNote(init_src, msg, template, args);
} else {
- root_msg = try sema.errMsg(block, init_src, template, args);
+ root_msg = try sema.errMsg(init_src, template, args);
}
} else {
const template = "missing tuple field with index {d}";
if (root_msg) |msg| {
- try sema.errNote(block, init_src, msg, template, .{i});
+ try sema.errNote(init_src, msg, template, .{i});
} else {
- root_msg = try sema.errMsg(block, init_src, template, .{i});
+ root_msg = try sema.errMsg(init_src, template, .{i});
}
}
} else {
@@ -20434,16 +20363,7 @@ fn finishStructInit(
}
if (root_msg) |msg| {
- if (mod.typeToStruct(struct_ty)) |struct_type| {
- const decl = mod.declPtr(struct_type.decl.unwrap().?);
- const fqn = try decl.fullyQualifiedName(mod);
- try mod.errNoteNonLazy(
- decl.srcLoc(mod),
- msg,
- "struct '{}' declared here",
- .{fqn.fmt(ip)},
- );
- }
+ try sema.addDeclaredHereNote(msg, struct_ty);
root_msg = null;
return sema.failWithOwnedErrorMsg(block, msg);
}
@@ -20470,9 +20390,10 @@ fn finishStructInit(
};
if (try sema.typeRequiresComptime(struct_ty)) {
- const decl = mod.declPtr(block.src_decl);
- const field_src = mod.initSrc(init_src.node_offset.x, decl, runtime_index);
- return sema.failWithNeededComptime(block, field_src, .{
+ return sema.failWithNeededComptime(block, block.src(.{ .init_elem = .{
+ .init_node_offset = init_src.offset.node_offset.x,
+ .elem_index = @intCast(runtime_index),
+ } }), .{
.needed_comptime_reason = "initializer of comptime only struct must be comptime-known",
});
}
@@ -20500,15 +20421,10 @@ fn finishStructInit(
return sema.makePtrConst(block, alloc);
}
- sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const decl = mod.declPtr(block.src_decl);
- const field_src = mod.initSrc(dest_src.node_offset.x, decl, runtime_index);
- try sema.requireRuntimeBlock(block, dest_src, field_src);
- unreachable;
- },
- else => |e| return e,
- };
+ try sema.requireRuntimeBlock(block, dest_src, block.src(.{ .init_elem = .{
+ .init_node_offset = init_src.offset.node_offset.x,
+ .elem_index = @intCast(runtime_index),
+ } }));
try sema.resolveStructFieldInits(struct_ty);
try sema.queueFullTypeResolution(struct_ty);
const struct_val = try block.addAggregateInit(struct_ty, field_inits);
@@ -20576,9 +20492,11 @@ fn structInitAnon(
field_ty.* = sema.typeOf(init).toIntern();
if (Type.fromInterned(field_ty.*).zigTypeTag(mod) == .Opaque) {
const msg = msg: {
- const decl = mod.declPtr(block.src_decl);
- const field_src = mod.initSrc(src.node_offset.x, decl, @intCast(i_usize));
- const msg = try sema.errMsg(block, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
+ const field_src = block.src(.{ .init_elem = .{
+ .init_node_offset = src.offset.node_offset.x,
+ .elem_index = @intCast(i_usize),
+ } });
+ const msg = try sema.errMsg(field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, Type.fromInterned(field_ty.*));
@@ -20610,15 +20528,10 @@ fn structInitAnon(
return sema.addConstantMaybeRef(tuple_val, is_ref);
};
- sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const decl = mod.declPtr(block.src_decl);
- const field_src = mod.initSrc(src.node_offset.x, decl, runtime_index);
- try sema.requireRuntimeBlock(block, src, field_src);
- unreachable;
- },
- else => |e| return e,
- };
+ try sema.requireRuntimeBlock(block, LazySrcLoc.unneeded, block.src(.{ .init_elem = .{
+ .init_node_offset = src.offset.node_offset.x,
+ .elem_index = @intCast(runtime_index),
+ } }));
if (is_ref) {
const target = mod.getTarget();
@@ -20697,15 +20610,19 @@ fn zirArrayInit(
const resolved_args = try gpa.alloc(Air.Inst.Ref, final_len);
defer gpa.free(resolved_args);
for (resolved_args, 0..) |*dest, i| {
+ const elem_src = block.src(.{ .init_elem = .{
+ .init_node_offset = src.offset.node_offset.x,
+ .elem_index = @intCast(i),
+ } });
// Less inits than needed.
if (i + 2 > args.len) if (is_tuple) {
const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();
if (default_val == .unreachable_value) {
const template = "missing tuple field with index {d}";
if (root_msg) |msg| {
- try sema.errNote(block, src, msg, template, .{i});
+ try sema.errNote(src, msg, template, .{i});
} else {
- root_msg = try sema.errMsg(block, src, template, .{i});
+ root_msg = try sema.errMsg(src, template, .{i});
}
} else {
dest.* = Air.internedToRef(default_val);
@@ -20722,29 +20639,17 @@ fn zirArrayInit(
array_ty.structFieldType(i, mod)
else
array_ty.elemType2(mod);
- dest.* = sema.coerce(block, elem_ty, resolved_arg, .unneeded) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const decl = mod.declPtr(block.src_decl);
- const elem_src = mod.initSrc(src.node_offset.x, decl, i);
- _ = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
- unreachable;
- },
- else => return err,
- };
+ dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
if (is_tuple) {
if (array_ty.structFieldIsComptime(i, mod))
try sema.resolveStructFieldInits(array_ty);
if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
const init_val = try sema.resolveValue(dest.*) orelse {
- const decl = mod.declPtr(block.src_decl);
- const elem_src = mod.initSrc(src.node_offset.x, decl, i);
return sema.failWithNeededComptime(block, elem_src, .{
.needed_comptime_reason = "value stored in comptime field must be comptime-known",
});
};
if (!field_val.eql(init_val, elem_ty, mod)) {
- const decl = mod.declPtr(block.src_decl);
- const elem_src = mod.initSrc(src.node_offset.x, decl, i);
return sema.failWithInvalidComptimeFieldStore(block, elem_src, array_ty, i);
}
}
@@ -20777,15 +20682,10 @@ fn zirArrayInit(
return sema.addConstantMaybeRef(result_val.toIntern(), is_ref);
};
- sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const decl = mod.declPtr(block.src_decl);
- const elem_src = mod.initSrc(src.node_offset.x, decl, runtime_index);
- try sema.requireRuntimeBlock(block, src, elem_src);
- unreachable;
- },
- else => return err,
- };
+ try sema.requireRuntimeBlock(block, LazySrcLoc.unneeded, block.src(.{ .init_elem = .{
+ .init_node_offset = src.offset.node_offset.x,
+ .elem_index = runtime_index,
+ } }));
try sema.queueFullTypeResolution(array_ty);
if (is_ref) {
@@ -20864,7 +20764,7 @@ fn arrayInitAnon(
types[i] = sema.typeOf(elem).toIntern();
if (Type.fromInterned(types[i]).zigTypeTag(mod) == .Opaque) {
const msg = msg: {
- const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
+ const msg = try sema.errMsg(operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
errdefer msg.destroy(gpa);
try sema.addDeclaredHereNote(msg, Type.fromInterned(types[i]));
@@ -20935,8 +20835,8 @@ fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.In
fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.FieldTypeRef, inst_data.payload_index).data;
- const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const field_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);
const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{
.needed_comptime_reason = "field name must be comptime-known",
@@ -20950,7 +20850,7 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
const ty_src = block.nodeOffset(inst_data.src_node);
- const field_name_src: LazySrcLoc = .{ .node_offset_field_name_init = inst_data.src_node };
+ const field_name_src = block.src(.{ .node_offset_field_name_init = inst_data.src_node });
const wrapped_aggregate_ty = sema.resolveType(block, ty_src, extra.container_type) catch |err| switch (err) {
// Since this is a ZIR instruction that returns a type, encountering
// generic poison should not result in a failed compilation, but the
@@ -20990,7 +20890,7 @@ fn fieldType(
.struct_type => {
const struct_type = ip.loadStructType(cur_ty.toIntern());
const field_index = struct_type.nameIndex(ip, field_name) orelse
- return sema.failWithBadStructFieldAccess(block, struct_type, field_src, field_name);
+ return sema.failWithBadStructFieldAccess(block, cur_ty, struct_type, field_src, field_name);
const field_ty = struct_type.field_types.get(ip)[field_index];
return Air.internedToRef(field_ty);
},
@@ -20999,7 +20899,7 @@ fn fieldType(
.Union => {
const union_obj = mod.typeToUnion(cur_ty).?;
const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse
- return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
+ return sema.failWithBadUnionFieldAccess(block, cur_ty, union_obj, field_src, field_name);
const field_ty = union_obj.field_types.get(ip)[field_index];
return Air.internedToRef(field_ty);
},
@@ -21050,14 +20950,14 @@ fn zirFrame(
block: *Block,
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
- const src = LazySrcLoc.nodeOffset(@bitCast(extended.operand));
+ const src = block.nodeOffset(@bitCast(extended.operand));
return sema.failWithUseOfAsync(block, src);
}
fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const ty = try sema.resolveType(block, operand_src, inst_data.operand);
if (ty.isNoReturn(mod)) {
return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});
@@ -21121,7 +21021,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const uncoerced_operand = try sema.resolveInst(inst_data.operand);
const operand = try sema.coerce(block, Type.anyerror, uncoerced_operand, operand_src);
@@ -21143,7 +21043,7 @@ fn zirAbs(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const operand = try sema.resolveInst(inst_data.operand);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand_ty = sema.typeOf(operand);
const scalar_ty = operand_ty.scalarType(mod);
@@ -21211,7 +21111,7 @@ fn zirUnaryMath(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const operand = try sema.resolveInst(inst_data.operand);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand_ty = sema.typeOf(operand);
const scalar_ty = operand_ty.scalarType(mod);
@@ -21233,7 +21133,7 @@ fn zirUnaryMath(
fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const src = block.nodeOffset(inst_data.src_node);
const operand = try sema.resolveInst(inst_data.operand);
const operand_ty = sema.typeOf(operand);
@@ -21243,7 +21143,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
try sema.resolveTypeLayout(operand_ty);
const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
.EnumLiteral => {
- const val = try sema.resolveConstDefinedValue(block, .unneeded, operand, undefined);
+ const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
return sema.addNullTerminatedStrLit(tag_name);
},
@@ -21266,13 +21166,12 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src);
if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| {
const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse {
- const enum_decl = mod.declPtr(enum_decl_index);
const msg = msg: {
- const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{}'", .{
- val.fmtValue(sema.mod, sema), enum_decl.name.fmt(ip),
+ const msg = try sema.errMsg(src, "no field with value '{}' in enum '{}'", .{
+ val.fmtValue(sema.mod, sema), mod.declPtr(enum_decl_index).name.fmt(ip),
});
errdefer msg.destroy(sema.gpa);
- try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{});
+ try sema.errNote(enum_ty.srcLoc(mod), msg, "declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -21303,10 +21202,10 @@ fn zirReify(
const ip = &mod.intern_pool;
const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
+ const src = block.nodeOffset(extra.node);
const type_info_ty = try sema.getBuiltinType("Type");
const uncasted_operand = try sema.resolveInst(extra.operand);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const operand_src = block.builtinCallArgSrc(extra.node, 0);
const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{
.needed_comptime_reason = "operand to @Type must be comptime-known",
@@ -21459,11 +21358,10 @@ fn zirReify(
} else if (ptr_size == .C) {
if (!try sema.validateExternType(elem_ty, .other)) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)});
errdefer msg.destroy(gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), elem_ty, .other);
+ try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other);
try sema.addDeclaredHereNote(msg, elem_ty);
break :msg msg;
@@ -21679,7 +21577,6 @@ fn zirReify(
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
block,
- mod.declPtr(block.src_decl).relativeToNodeIndex(src.node_offset.x),
Value.fromInterned(wip_ty.index),
name_strategy,
"opaque",
@@ -21879,7 +21776,6 @@ fn reifyEnum(
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
block,
- mod.declPtr(block.src_decl).relativeToNodeIndex(src.node_offset.x),
Value.fromInterned(wip_ty.index),
name_strategy,
"enum",
@@ -21913,17 +21809,17 @@ fn reifyEnum(
if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| {
return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {
.name => msg: {
- const msg = try sema.errMsg(block, src, "duplicate enum field '{}'", .{field_name.fmt(ip)});
+ const msg = try sema.errMsg(src, "duplicate enum field '{}'", .{field_name.fmt(ip)});
errdefer msg.destroy(gpa);
_ = conflict.prev_field_idx; // TODO: this note is incorrect
- try sema.errNote(block, src, msg, "other field here", .{});
+ try sema.errNote(src, msg, "other field here", .{});
break :msg msg;
},
.value => msg: {
- const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod, sema)});
+ const msg = try sema.errMsg(src, "enum tag value {} already taken", .{field_value_val.fmtValue(mod, sema)});
errdefer msg.destroy(gpa);
_ = conflict.prev_field_idx; // TODO: this note is incorrect
- try sema.errNote(block, src, msg, "other enum tag value here", .{});
+ try sema.errNote(src, msg, "other enum tag value here", .{});
break :msg msg;
},
});
@@ -22026,7 +21922,6 @@ fn reifyUnion(
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
block,
- mod.declPtr(block.src_decl).relativeToNodeIndex(src.node_offset.x),
Value.fromInterned(wip_ty.index),
name_strategy,
"union",
@@ -22082,7 +21977,7 @@ fn reifyUnion(
}
if (tag_ty_fields_len > fields_len) return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "enum fields missing in union", .{});
+ const msg = try sema.errMsg(src, "enum fields missing in union", .{});
errdefer msg.destroy(gpa);
var it = seen_tags.iterator(.{ .kind = .unset });
while (it.next()) |enum_index| {
@@ -22135,7 +22030,7 @@ fn reifyUnion(
const field_ty = Type.fromInterned(field_ty_ip);
if (field_ty.zigTypeTag(mod) == .Opaque) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
+ const msg = try sema.errMsg(src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
errdefer msg.destroy(gpa);
try sema.addDeclaredHereNote(msg, field_ty);
@@ -22144,22 +22039,20 @@ fn reifyUnion(
}
if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
errdefer msg.destroy(gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), field_ty, .union_field);
+ try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field);
try sema.addDeclaredHereNote(msg, field_ty);
break :msg msg;
});
} else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
errdefer msg.destroy(gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotPacked(msg, src_decl.toSrcLoc(src, mod), field_ty);
+ try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
try sema.addDeclaredHereNote(msg, field_ty);
break :msg msg;
@@ -22285,7 +22178,6 @@ fn reifyStruct(
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
block,
- mod.declPtr(block.src_decl).relativeToNodeIndex(src.node_offset.x),
Value.fromInterned(wip_ty.index),
name_strategy,
"struct",
@@ -22376,7 +22268,7 @@ fn reifyStruct(
if (field_ty.zigTypeTag(mod) == .Opaque) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
+ const msg = try sema.errMsg(src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
errdefer msg.destroy(gpa);
try sema.addDeclaredHereNote(msg, field_ty);
@@ -22385,7 +22277,7 @@ fn reifyStruct(
}
if (field_ty.zigTypeTag(mod) == .NoReturn) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "struct fields cannot be 'noreturn'", .{});
+ const msg = try sema.errMsg(src, "struct fields cannot be 'noreturn'", .{});
errdefer msg.destroy(gpa);
try sema.addDeclaredHereNote(msg, field_ty);
@@ -22394,22 +22286,20 @@ fn reifyStruct(
}
if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
errdefer msg.destroy(gpa);
- const src_decl = sema.mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), field_ty, .struct_field);
+ try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field);
try sema.addDeclaredHereNote(msg, field_ty);
break :msg msg;
});
} else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
errdefer msg.destroy(gpa);
- const src_decl = sema.mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotPacked(msg, src_decl.toSrcLoc(src, mod), field_ty);
+ try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
try sema.addDeclaredHereNote(msg, field_ty);
break :msg msg;
@@ -22424,7 +22314,7 @@ fn reifyStruct(
sema.resolveTypeLayout(field_ty) catch |err| switch (err) {
error.AnalysisFail => {
const msg = sema.err orelse return err;
- try sema.errNote(block, src, msg, "while checking a field of this struct", .{});
+ try sema.errNote(src, msg, "while checking a field of this struct", .{});
return err;
},
else => return err,
@@ -22455,22 +22345,20 @@ fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.In
}
fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
- const mod = sema.mod;
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const va_list_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const va_list_src = block.builtinCallArgSrc(extra.node, 0);
+ const ty_src = block.builtinCallArgSrc(extra.node, 1);
const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.lhs);
const arg_ty = try sema.resolveType(block, ty_src, extra.rhs);
if (!try sema.validateExternType(arg_ty, .param_ty)) {
const msg = msg: {
- const msg = try sema.errMsg(block, ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(ty_src, "cannot get '{}' from variadic argument", .{arg_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- const src_decl = sema.mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(ty_src, mod), arg_ty, .param_ty);
+ try sema.explainWhyTypeIsNotExtern(msg, ty_src, arg_ty, .param_ty);
try sema.addDeclaredHereNote(msg, arg_ty);
break :msg msg;
@@ -22484,8 +22372,8 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const va_list_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const va_list_src = block.builtinCallArgSrc(extra.node, 0);
const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
const va_list_ty = try sema.getBuiltinType("VaList");
@@ -22496,8 +22384,8 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const va_list_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const va_list_src = block.builtinCallArgSrc(extra.node, 0);
const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
@@ -22506,7 +22394,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
}
fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
- const src = LazySrcLoc.nodeOffset(@bitCast(extended.operand));
+ const src = block.nodeOffset(@bitCast(extended.operand));
const va_list_ty = try sema.getBuiltinType("VaList");
try sema.requireRuntimeBlock(block, src, null);
@@ -22521,7 +22409,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const ip = &mod.intern_pool;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const ty = try sema.resolveType(block, ty_src, inst_data.operand);
const type_name = try ip.getOrPutStringFmt(sema.gpa, "{}", .{ty.fmt(mod)}, .no_embedded_nulls);
@@ -22545,7 +22433,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intFromFloat");
const operand = try sema.resolveInst(extra.rhs);
const operand_ty = sema.typeOf(operand);
@@ -22627,7 +22515,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatFromInt");
const operand = try sema.resolveInst(extra.rhs);
const operand_ty = sema.typeOf(operand);
@@ -22671,7 +22559,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand_res = try sema.resolveInst(extra.rhs);
const uncoerced_operand_ty = sema.typeOf(operand_res);
@@ -22694,9 +22582,9 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
if (ptr_ty.isSlice(mod)) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "slice length cannot be inferred from address", .{});
+ try sema.errNote(src, msg, "slice length cannot be inferred from address", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -22721,11 +22609,10 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
}
if (try sema.typeRequiresComptime(ptr_ty)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "pointer to comptime-only type '{}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsComptime(msg, src_decl.toSrcLoc(src, mod), ptr_ty);
+ try sema.explainWhyTypeIsComptime(msg, src, ptr_ty);
break :msg msg;
});
}
@@ -22810,8 +22697,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
const mod = sema.mod;
const ip = &mod.intern_pool;
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const operand_src = block.builtinCallArgSrc(extra.node, 0);
const base_dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_opt, "@errorCast");
const operand = try sema.resolveInst(extra.rhs);
const base_operand_ty = sema.typeOf(operand);
@@ -22831,12 +22718,12 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
base_dest_ty.errorUnionPayload(mod).toIntern() != base_operand_ty.errorUnionPayload(mod).toIntern())
{
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "payload types of error unions must match", .{});
+ const msg = try sema.errMsg(src, "payload types of error unions must match", .{});
errdefer msg.destroy(sema.gpa);
const dest_ty = base_dest_ty.errorUnionPayload(mod);
const operand_ty = base_operand_ty.errorUnionPayload(mod);
- try sema.errNote(block, src, msg, "destination payload is '{}'", .{dest_ty.fmt(mod)});
- try sema.errNote(block, src, msg, "operand payload is '{}'", .{operand_ty.fmt(mod)});
+ try sema.errNote(src, msg, "destination payload is '{}'", .{dest_ty.fmt(mod)});
+ try sema.errNote(src, msg, "operand payload is '{}'", .{operand_ty.fmt(mod)});
try addDeclaredHereNote(sema, msg, dest_ty);
try addDeclaredHereNote(sema, msg, operand_ty);
break :msg msg;
@@ -22935,8 +22822,8 @@ fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa
const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const operand_src: LazySrcLoc = .{ .node_offset_ptrcast_operand = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const operand_src = block.src(.{ .node_offset_ptrcast_operand = extra.node });
const operand = try sema.resolveInst(extra.rhs);
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, flags.needResultTypeBuiltinName());
return sema.ptrCastFull(
@@ -22953,7 +22840,7 @@ fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa
fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, "@ptrCast");
const operand = try sema.resolveInst(extra.rhs);
@@ -23023,7 +22910,7 @@ fn ptrCastFull(
if (src_info.flags.size == .C) break :check_size;
if (dest_info.flags.size == .C) break :check_size;
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "cannot implicitly convert {s} pointer to {s} pointer", .{
+ const msg = try sema.errMsg(src, "cannot implicitly convert {s} pointer to {s} pointer", .{
pointerSizeString(src_info.flags.size),
pointerSizeString(dest_info.flags.size),
});
@@ -23032,9 +22919,9 @@ fn ptrCastFull(
(src_info.flags.size == .Slice or
(src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array)))
{
- try sema.errNote(block, src, msg, "use 'ptr' field to convert slice to many pointer", .{});
+ try sema.errNote(src, msg, "use 'ptr' field to convert slice to many pointer", .{});
} else {
- try sema.errNote(block, src, msg, "use @ptrCast to change pointer size", .{});
+ try sema.errNote(src, msg, "use @ptrCast to change pointer size", .{});
}
break :msg msg;
});
@@ -23059,13 +22946,13 @@ fn ptrCastFull(
);
if (imc_res == .ok) break :check_child;
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "pointer element type '{}' cannot coerce into element type '{}'", .{
+ const msg = try sema.errMsg(src, "pointer element type '{}' cannot coerce into element type '{}'", .{
src_child.fmt(mod),
dest_child.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
- try imc_res.report(sema, block, src, msg);
- try sema.errNote(block, src, msg, "use @ptrCast to cast pointer element type", .{});
+ try imc_res.report(sema, src, msg);
+ try sema.errNote(src, msg, "use @ptrCast to cast pointer element type", .{});
break :msg msg;
});
}
@@ -23087,41 +22974,41 @@ fn ptrCastFull(
}
return sema.failWithOwnedErrorMsg(block, msg: {
const msg = if (src_info.sentinel == .none) blk: {
- break :blk try sema.errMsg(block, src, "destination pointer requires '{}' sentinel", .{
+ break :blk try sema.errMsg(src, "destination pointer requires '{}' sentinel", .{
Value.fromInterned(dest_info.sentinel).fmtValue(mod, sema),
});
} else blk: {
- break :blk try sema.errMsg(block, src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
+ break :blk try sema.errMsg(src, "pointer sentinel '{}' cannot coerce into pointer sentinel '{}'", .{
Value.fromInterned(src_info.sentinel).fmtValue(mod, sema),
Value.fromInterned(dest_info.sentinel).fmtValue(mod, sema),
});
};
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "use @ptrCast to cast pointer sentinel", .{});
+ try sema.errNote(src, msg, "use @ptrCast to cast pointer sentinel", .{});
break :msg msg;
});
}
if (src_info.packed_offset.host_size != dest_info.packed_offset.host_size) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "pointer host size '{}' cannot coerce into pointer host size '{}'", .{
+ const msg = try sema.errMsg(src, "pointer host size '{}' cannot coerce into pointer host size '{}'", .{
src_info.packed_offset.host_size,
dest_info.packed_offset.host_size,
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "use @ptrCast to cast pointer host size", .{});
+ try sema.errNote(src, msg, "use @ptrCast to cast pointer host size", .{});
break :msg msg;
});
}
if (src_info.packed_offset.bit_offset != dest_info.packed_offset.bit_offset) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "pointer bit offset '{}' cannot coerce into pointer bit offset '{}'", .{
+ const msg = try sema.errMsg(src, "pointer bit offset '{}' cannot coerce into pointer bit offset '{}'", .{
src_info.packed_offset.bit_offset,
dest_info.packed_offset.bit_offset,
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "use @ptrCast to cast pointer bit offset", .{});
+ try sema.errNote(src, msg, "use @ptrCast to cast pointer bit offset", .{});
break :msg msg;
});
}
@@ -23133,12 +23020,12 @@ fn ptrCastFull(
if (dest_allows_zero) break :check_allowzero;
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "'{}' could have null values which are illegal in type '{}'", .{
+ const msg = try sema.errMsg(src, "'{}' could have null values which are illegal in type '{}'", .{
operand_ty.fmt(mod),
dest_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "use @ptrCast to assert the pointer is not null", .{});
+ try sema.errNote(src, msg, "use @ptrCast to assert the pointer is not null", .{});
break :msg msg;
});
}
@@ -23159,15 +23046,15 @@ fn ptrCastFull(
if (!flags.align_cast) {
if (dest_align.compare(.gt, src_align)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "{s} increases pointer alignment", .{operation});
+ const msg = try sema.errMsg(src, "{s} increases pointer alignment", .{operation});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, operand_src, msg, "'{}' has alignment '{d}'", .{
+ try sema.errNote(operand_src, msg, "'{}' has alignment '{d}'", .{
operand_ty.fmt(mod), src_align.toByteUnits() orelse 0,
});
- try sema.errNote(block, src, msg, "'{}' has alignment '{d}'", .{
+ try sema.errNote(src, msg, "'{}' has alignment '{d}'", .{
dest_ty.fmt(mod), dest_align.toByteUnits() orelse 0,
});
- try sema.errNote(block, src, msg, "use @alignCast to assert pointer alignment", .{});
+ try sema.errNote(src, msg, "use @alignCast to assert pointer alignment", .{});
break :msg msg;
});
}
@@ -23176,15 +23063,15 @@ fn ptrCastFull(
if (!flags.addrspace_cast) {
if (src_info.flags.address_space != dest_info.flags.address_space) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "{s} changes pointer address space", .{operation});
+ const msg = try sema.errMsg(src, "{s} changes pointer address space", .{operation});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, operand_src, msg, "'{}' has address space '{s}'", .{
+ try sema.errNote(operand_src, msg, "'{}' has address space '{s}'", .{
operand_ty.fmt(mod), @tagName(src_info.flags.address_space),
});
- try sema.errNote(block, src, msg, "'{}' has address space '{s}'", .{
+ try sema.errNote(src, msg, "'{}' has address space '{s}'", .{
dest_ty.fmt(mod), @tagName(dest_info.flags.address_space),
});
- try sema.errNote(block, src, msg, "use @addrSpaceCast to cast pointer address space", .{});
+ try sema.errNote(src, msg, "use @addrSpaceCast to cast pointer address space", .{});
break :msg msg;
});
}
@@ -23192,9 +23079,9 @@ fn ptrCastFull(
// Some address space casts are always disallowed
if (!target_util.addrSpaceCastIsValid(mod.getTarget(), src_info.flags.address_space, dest_info.flags.address_space)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "invalid address space cast", .{});
+ const msg = try sema.errMsg(src, "invalid address space cast", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, operand_src, msg, "address space '{s}' is not compatible with address space '{s}'", .{
+ try sema.errNote(operand_src, msg, "address space '{s}' is not compatible with address space '{s}'", .{
@tagName(src_info.flags.address_space),
@tagName(dest_info.flags.address_space),
});
@@ -23206,9 +23093,9 @@ fn ptrCastFull(
if (!flags.const_cast) {
if (src_info.flags.is_const and !dest_info.flags.is_const) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "{s} discards const qualifier", .{operation});
+ const msg = try sema.errMsg(src, "{s} discards const qualifier", .{operation});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "use @constCast to discard const qualifier", .{});
+ try sema.errNote(src, msg, "use @constCast to discard const qualifier", .{});
break :msg msg;
});
}
@@ -23217,9 +23104,9 @@ fn ptrCastFull(
if (!flags.volatile_cast) {
if (src_info.flags.is_volatile and !dest_info.flags.is_volatile) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "{s} discards volatile qualifier", .{operation});
+ const msg = try sema.errMsg(src, "{s} discards volatile qualifier", .{operation});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "use @volatileCast to discard volatile qualifier", .{});
+ try sema.errNote(src, msg, "use @volatileCast to discard volatile qualifier", .{});
break :msg msg;
});
}
@@ -23368,8 +23255,8 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const operand_src: LazySrcLoc = .{ .node_offset_ptrcast_operand = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const operand_src = block.src(.{ .node_offset_ptrcast_operand = extra.node });
const operand = try sema.resolveInst(extra.operand);
const operand_ty = sema.typeOf(operand);
try sema.checkPtrOperand(block, operand_src, operand_ty);
@@ -23400,7 +23287,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@truncate");
const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, src);
@@ -23438,16 +23325,15 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
if (operand_info.bits < dest_info.bits) {
const msg = msg: {
const msg = try sema.errMsg(
- block,
src,
"destination type '{}' has more bits than source type '{}'",
.{ dest_ty.fmt(mod), operand_ty.fmt(mod) },
);
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "destination type has {d} bits", .{
+ try sema.errNote(src, msg, "destination type has {d} bits", .{
dest_info.bits,
});
- try sema.errNote(block, operand_src, msg, "operand type has {d} bits", .{
+ try sema.errNote(operand_src, msg, "operand type has {d} bits", .{
operand_info.bits,
});
break :msg msg;
@@ -23490,7 +23376,7 @@ fn zirBitCount(
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand = try sema.resolveInst(inst_data.operand);
const operand_ty = sema.typeOf(operand);
_ = try sema.checkIntOrVector(block, operand, operand_src);
@@ -23544,7 +23430,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand = try sema.resolveInst(inst_data.operand);
const operand_ty = sema.typeOf(operand);
const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);
@@ -23600,7 +23486,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
const src = block.nodeOffset(inst_data.src_node);
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const operand = try sema.resolveInst(inst_data.operand);
const operand_ty = sema.typeOf(operand);
const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);
@@ -23658,9 +23544,9 @@ fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u64 {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node };
- const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
+ const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
+ const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
+ const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const ty = try sema.resolveType(block, lhs_src, extra.lhs);
@@ -23773,14 +23659,13 @@ fn checkPtrOperand(
.Fn => {
const msg = msg: {
const msg = try sema.errMsg(
- block,
ty_src,
"expected pointer, found '{}'",
.{ty.fmt(mod)},
);
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, ty_src, msg, "use '&' to obtain a function pointer", .{});
+ try sema.errNote(ty_src, msg, "use '&' to obtain a function pointer", .{});
break :msg msg;
};
@@ -23805,14 +23690,13 @@ fn checkPtrType(
.Fn => {
const msg = msg: {
const msg = try sema.errMsg(
- block,
ty_src,
"expected pointer type, found '{}'",
.{ty.fmt(mod)},
);
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, ty_src, msg, "use '*const ' to make a function pointer type", .{});
+ try sema.errNote(ty_src, msg, "use '*const ' to make a function pointer type", .{});
break :msg msg;
};
@@ -24066,26 +23950,26 @@ fn checkVectorizableBinaryOperands(
const rhs_len = rhs_ty.arrayLen(mod);
if (lhs_len != rhs_len) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "vector length mismatch", .{});
+ const msg = try sema.errMsg(src, "vector length mismatch", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, lhs_src, msg, "length {d} here", .{lhs_len});
- try sema.errNote(block, rhs_src, msg, "length {d} here", .{rhs_len});
+ try sema.errNote(lhs_src, msg, "length {d} here", .{lhs_len});
+ try sema.errNote(rhs_src, msg, "length {d} here", .{rhs_len});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
}
} else {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "mixed scalar and vector operands: '{}' and '{}'", .{
+ const msg = try sema.errMsg(src, "mixed scalar and vector operands: '{}' and '{}'", .{
lhs_ty.fmt(mod), rhs_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
if (lhs_is_vector) {
- try sema.errNote(block, lhs_src, msg, "vector here", .{});
- try sema.errNote(block, rhs_src, msg, "scalar here", .{});
+ try sema.errNote(lhs_src, msg, "vector here", .{});
+ try sema.errNote(rhs_src, msg, "scalar here", .{});
} else {
- try sema.errNote(block, lhs_src, msg, "scalar here", .{});
- try sema.errNote(block, rhs_src, msg, "vector here", .{});
+ try sema.errNote(lhs_src, msg, "scalar here", .{});
+ try sema.errNote(rhs_src, msg, "vector here", .{});
}
break :msg msg;
};
@@ -24093,12 +23977,6 @@ fn checkVectorizableBinaryOperands(
}
}
-fn maybeOptionsSrc(sema: *Sema, block: *Block, base_src: LazySrcLoc, wanted: []const u8) LazySrcLoc {
- if (base_src == .unneeded) return .unneeded;
- const mod = sema.mod;
- return mod.optionsSrc(mod.declPtr(block.src_decl), base_src, wanted);
-}
-
fn resolveExportOptions(
sema: *Sema,
block: *Block,
@@ -24112,10 +23990,10 @@ fn resolveExportOptions(
const air_ref = try sema.resolveInst(zir_ref);
const options = try sema.coerce(block, export_options_ty, air_ref, src);
- const name_src = sema.maybeOptionsSrc(block, src, "name");
- const linkage_src = sema.maybeOptionsSrc(block, src, "linkage");
- const section_src = sema.maybeOptionsSrc(block, src, "section");
- const visibility_src = sema.maybeOptionsSrc(block, src, "visibility");
+ const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
+ const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node });
+ const section_src = block.src(.{ .init_field_section = src.offset.node_offset_builtin_call_arg.builtin_call_node });
+ const visibility_src = block.src(.{ .init_field_visibility = src.offset.node_offset_builtin_call_arg.builtin_call_node });
const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name", .no_embedded_nulls), name_src);
const name = try sema.toConstString(block, name_src, name_operand, .{
@@ -24212,14 +24090,14 @@ fn zirCmpxchg(
1 => .cmpxchg_strong,
else => unreachable,
};
- const src = LazySrcLoc.nodeOffset(extra.node);
+ const src = block.nodeOffset(extra.node);
// zig fmt: off
- const elem_ty_src : LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
- const expected_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node };
- const new_value_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = extra.node };
- const success_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg4 = extra.node };
- const failure_order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg5 = extra.node };
+ const elem_ty_src = block.builtinCallArgSrc(extra.node, 0);
+ const ptr_src = block.builtinCallArgSrc(extra.node, 1);
+ const expected_src = block.builtinCallArgSrc(extra.node, 2);
+ const new_value_src = block.builtinCallArgSrc(extra.node, 3);
+ const success_order_src = block.builtinCallArgSrc(extra.node, 4);
+ const failure_order_src = block.builtinCallArgSrc(extra.node, 5);
// zig fmt: on
const expected_value = try sema.resolveInst(extra.expected_value);
const elem_ty = sema.typeOf(expected_value);
@@ -24309,7 +24187,7 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const scalar_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
+ const scalar_src = block.builtinCallArgSrc(inst_data.src_node, 0);
const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@splat");
if (!dest_ty.isVector(mod)) return sema.fail(block, src, "expected vector type, found '{}'", .{dest_ty.fmt(mod)});
@@ -24337,8 +24215,8 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
- const op_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, "ReduceOp", .{
.needed_comptime_reason = "@reduce operation must be comptime-known",
});
@@ -24409,8 +24287,8 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Shuffle, inst_data.payload_index).data;
- const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const mask_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node };
+ const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const mask_src = block.builtinCallArgSrc(inst_data.src_node, 3);
const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
try sema.checkVectorElemType(block, elem_ty_src, elem_ty);
@@ -24445,9 +24323,9 @@ fn analyzeShuffle(
mask_len: u32,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
- const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = src_node };
- const b_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = src_node };
- const mask_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = src_node };
+ const a_src = block.builtinCallArgSrc(src_node, 1);
+ const b_src = block.builtinCallArgSrc(src_node, 2);
+ const mask_src = block.builtinCallArgSrc(src_node, 3);
var a = a_arg;
var b = b_arg;
@@ -24511,16 +24389,16 @@ fn analyzeShuffle(
}
if (unsigned >= operand_info[chosen][0]) {
const msg = msg: {
- const msg = try sema.errMsg(block, mask_src, "mask index '{d}' has out-of-bounds selection", .{i});
+ const msg = try sema.errMsg(mask_src, "mask index '{d}' has out-of-bounds selection", .{i});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{
+ try sema.errNote(operand_info[chosen][1], msg, "selected index '{d}' out of bounds of '{}'", .{
unsigned,
operand_info[chosen][2].fmt(sema.mod),
});
if (chosen == 0) {
- try sema.errNote(block, b_src, msg, "selections from the second vector are specified with negative numbers", .{});
+ try sema.errNote(b_src, msg, "selections from the second vector are specified with negative numbers", .{});
}
break :msg msg;
@@ -24598,11 +24476,11 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
const mod = sema.mod;
const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
- const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
- const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node };
- const b_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = extra.node };
+ const src = block.nodeOffset(extra.node);
+ const elem_ty_src = block.builtinCallArgSrc(extra.node, 0);
+ const pred_src = block.builtinCallArgSrc(extra.node, 1);
+ const a_src = block.builtinCallArgSrc(extra.node, 2);
+ const b_src = block.builtinCallArgSrc(extra.node, 3);
const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
try sema.checkVectorElemType(block, elem_ty_src, elem_ty);
@@ -24689,9 +24567,9 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.AtomicLoad, inst_data.payload_index).data;
// zig fmt: off
- const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
- const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
+ const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 1);
+ const order_src = block.builtinCallArgSrc(inst_data.src_node, 2);
// zig fmt: on
const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
const uncasted_ptr = try sema.resolveInst(extra.ptr);
@@ -24738,11 +24616,11 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
// zig fmt: off
- const elem_ty_src : LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
- const op_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
- const operand_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node };
- const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg4 = inst_data.src_node };
+ const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 1);
+ const op_src = block.builtinCallArgSrc(inst_data.src_node, 2);
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 3);
+ const order_src = block.builtinCallArgSrc(inst_data.src_node, 4);
// zig fmt: on
const operand = try sema.resolveInst(extra.operand);
const elem_ty = sema.typeOf(operand);
@@ -24823,10 +24701,10 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const extra = sema.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
// zig fmt: off
- const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const ptr_src : LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
- const operand_src : LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
- const order_src : LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node };
+ const elem_ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 1);
+ const operand_src = block.builtinCallArgSrc(inst_data.src_node, 2);
+ const order_src = block.builtinCallArgSrc(inst_data.src_node, 3);
// zig fmt: on
const operand = try sema.resolveInst(extra.operand);
const elem_ty = sema.typeOf(operand);
@@ -24859,9 +24737,9 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
const extra = sema.code.extraData(Zir.Inst.MulAdd, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const mulend1_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
- const mulend2_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
- const addend_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node };
+ const mulend1_src = block.builtinCallArgSrc(inst_data.src_node, 1);
+ const mulend2_src = block.builtinCallArgSrc(inst_data.src_node, 2);
+ const addend_src = block.builtinCallArgSrc(inst_data.src_node, 3);
const addend = try sema.resolveInst(extra.addend);
const ty = sema.typeOf(addend);
@@ -24924,9 +24802,9 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const mod = sema.mod;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
- const modifier_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const func_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
- const args_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
+ const modifier_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const func_src = block.builtinCallArgSrc(inst_data.src_node, 1);
+ const args_src = block.builtinCallArgSrc(inst_data.src_node, 2);
const call_src = block.nodeOffset(inst_data.src_node);
const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
@@ -25022,8 +24900,8 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
assert(!flags.ptr_cast);
const inst_src = block.nodeOffset(extra.src_node);
- const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.src_node };
- const field_ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.src_node };
+ const field_name_src = block.builtinCallArgSrc(extra.src_node, 0);
+ const field_ptr_src = block.builtinCallArgSrc(extra.src_node, 1);
const parent_ptr_ty = try sema.resolveDestType(block, inst_src, extra.parent_ptr_type, .remove_eu, "@fieldParentPtr");
try sema.checkPtrType(block, inst_src, parent_ptr_ty, true);
@@ -25212,9 +25090,9 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte
};
if (ptr.byte_offset < byte_subtract) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "pointer computation here causes undefined behavior", .{});
+ const msg = try sema.errMsg(src, "pointer computation here causes undefined behavior", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "resulting pointer exceeds bounds of containing value which may trigger overflow", .{});
+ try sema.errNote(src, msg, "resulting pointer exceeds bounds of containing value which may trigger overflow", .{});
break :msg msg;
});
}
@@ -25232,8 +25110,8 @@ fn zirMinMax(
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const lhs = try sema.resolveInst(extra.lhs);
const rhs = try sema.resolveInst(extra.rhs);
try sema.checkNumericType(block, lhs_src, sema.typeOf(lhs));
@@ -25249,22 +25127,14 @@ fn zirMinMaxMulti(
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.NodeMultiOp, extended.operand);
const src_node = extra.data.src_node;
- const src = LazySrcLoc.nodeOffset(src_node);
+ const src = block.nodeOffset(src_node);
const operands = sema.code.refSlice(extra.end, extended.small);
const air_refs = try sema.arena.alloc(Air.Inst.Ref, operands.len);
const operand_srcs = try sema.arena.alloc(LazySrcLoc, operands.len);
for (operands, air_refs, operand_srcs, 0..) |zir_ref, *air_ref, *op_src, i| {
- op_src.* = switch (i) {
- 0 => .{ .node_offset_builtin_call_arg0 = src_node },
- 1 => .{ .node_offset_builtin_call_arg1 = src_node },
- 2 => .{ .node_offset_builtin_call_arg2 = src_node },
- 3 => .{ .node_offset_builtin_call_arg3 = src_node },
- 4 => .{ .node_offset_builtin_call_arg4 = src_node },
- 5 => .{ .node_offset_builtin_call_arg5 = src_node },
- else => src, // TODO: better source location
- };
+ op_src.* = block.builtinCallArgSrc(src_node, @intCast(i));
air_ref.* = try sema.resolveInst(zir_ref);
try sema.checkNumericType(block, op_src.*, sema.typeOf(air_ref.*));
}
@@ -25533,8 +25403,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const dest_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const src_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const dest_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const src_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const dest_ptr = try sema.resolveInst(extra.lhs);
const src_ptr = try sema.resolveInst(extra.rhs);
const dest_ty = sema.typeOf(dest_ptr);
@@ -25550,12 +25420,12 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
if (dest_len == .none and src_len == .none) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "unknown @memcpy length", .{});
+ const msg = try sema.errMsg(src, "unknown @memcpy length", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, dest_src, msg, "destination type '{}' provides no length", .{
+ try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{
dest_ty.fmt(sema.mod),
});
- try sema.errNote(block, src_src, msg, "source type '{}' provides no length", .{
+ try sema.errNote(src_src, msg, "source type '{}' provides no length", .{
src_ty.fmt(sema.mod),
});
break :msg msg;
@@ -25572,12 +25442,12 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
if (try sema.resolveDefinedValue(block, src_src, src_len)) |src_len_val| {
if (!(try sema.valuesEqual(dest_len_val, src_len_val, Type.usize))) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "non-matching @memcpy lengths", .{});
+ const msg = try sema.errMsg(src, "non-matching @memcpy lengths", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, dest_src, msg, "length {} here", .{
+ try sema.errNote(dest_src, msg, "length {} here", .{
dest_len_val.fmtValue(sema.mod, sema),
});
- try sema.errNote(block, src_src, msg, "length {} here", .{
+ try sema.errNote(src_src, msg, "length {} here", .{
src_len_val.fmtValue(sema.mod, sema),
});
break :msg msg;
@@ -25685,7 +25555,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
} else if (dest_len == .none and len_val == null) {
// Change the dest to a slice, since its type must have the length.
const dest_ptr_ptr = try sema.analyzeRef(block, dest_src, new_dest_ptr);
- new_dest_ptr = try sema.analyzeSlice(block, dest_src, dest_ptr_ptr, .zero, src_len, .none, .unneeded, dest_src, dest_src, dest_src, false);
+ new_dest_ptr = try sema.analyzeSlice(block, dest_src, dest_ptr_ptr, .zero, src_len, .none, LazySrcLoc.unneeded, dest_src, dest_src, dest_src, false);
const new_src_ptr_ty = sema.typeOf(new_src_ptr);
if (new_src_ptr_ty.isSlice(mod)) {
new_src_ptr = try sema.analyzeSlicePtr(block, src_src, new_src_ptr, new_src_ptr_ty);
@@ -25753,8 +25623,8 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
const src = block.nodeOffset(inst_data.src_node);
- const dest_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const value_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
+ const dest_src = block.builtinCallArgSrc(inst_data.src_node, 0);
+ const value_src = block.builtinCallArgSrc(inst_data.src_node, 1);
const dest_ptr = try sema.resolveInst(extra.lhs);
const uncoerced_elem = try sema.resolveInst(extra.rhs);
const dest_ptr_ty = sema.typeOf(dest_ptr);
@@ -25776,9 +25646,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
.Many, .C => {},
}
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, src, "unknown @memset length", .{});
+ const msg = try sema.errMsg(src, "unknown @memset length", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, dest_src, msg, "destination type '{}' provides no length", .{
+ try sema.errNote(dest_src, msg, "destination type '{}' provides no length", .{
dest_ptr_ty.fmt(mod),
});
break :msg msg;
@@ -25831,7 +25701,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
fn zirBuiltinAsyncCall(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
+ const src = block.nodeOffset(extra.node);
return sema.failWithUseOfAsync(block, src);
}
@@ -25858,7 +25728,7 @@ fn zirAwaitNosuspend(
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src = LazySrcLoc.nodeOffset(extra.node);
+ const src = block.nodeOffset(extra.node);
return sema.failWithUseOfAsync(block, src);
}
@@ -25870,8 +25740,8 @@ fn zirVarExtended(
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand);
- const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 };
- const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 };
+ const ty_src = block.src(.{ .node_offset_var_decl_ty = 0 });
+ const init_src = block.src(.{ .node_offset_var_decl_init = 0 });
const small: Zir.Inst.ExtendedVar.Small = @bitCast(extended.small);
var extra_index: usize = extra.end;
@@ -25936,11 +25806,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const extra = sema.code.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
const target = mod.getTarget();
- const align_src: LazySrcLoc = .{ .node_offset_fn_type_align = inst_data.src_node };
- const addrspace_src: LazySrcLoc = .{ .node_offset_fn_type_addrspace = inst_data.src_node };
- const section_src: LazySrcLoc = .{ .node_offset_fn_type_section = inst_data.src_node };
- const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node };
- const ret_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = inst_data.src_node };
+ const align_src = block.src(.{ .node_offset_fn_type_align = inst_data.src_node });
+ const addrspace_src = block.src(.{ .node_offset_fn_type_addrspace = inst_data.src_node });
+ const section_src = block.src(.{ .node_offset_fn_type_section = inst_data.src_node });
+ const cc_src = block.src(.{ .node_offset_fn_type_cc = inst_data.src_node });
+ const ret_src = block.src(.{ .node_offset_fn_type_ret_ty = inst_data.src_node });
const has_body = extra.data.body_len != 0;
var extra_index: usize = extra.end;
@@ -26167,7 +26037,7 @@ fn zirCUndef(
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src = block.builtinCallArgSrc(extra.node, 0);
const name = try sema.resolveConstString(block, src, extra.operand, .{
.needed_comptime_reason = "name of macro being undefined must be comptime-known",
@@ -26182,7 +26052,7 @@ fn zirCInclude(
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src = block.builtinCallArgSrc(extra.node, 0);
const name = try sema.resolveConstString(block, src, extra.operand, .{
.needed_comptime_reason = "path being included must be comptime-known",
@@ -26198,8 +26068,8 @@ fn zirCDefine(
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
- const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const val_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
+ const name_src = block.builtinCallArgSrc(extra.node, 0);
+ const val_src = block.builtinCallArgSrc(extra.node, 1);
const name = try sema.resolveConstString(block, name_src, extra.lhs, .{
.needed_comptime_reason = "name of macro being undefined must be comptime-known",
@@ -26222,8 +26092,8 @@ fn zirWasmMemorySize(
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const index_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const builtin_src = LazySrcLoc.nodeOffset(extra.node);
+ const index_src = block.builtinCallArgSrc(extra.node, 0);
+ const builtin_src = block.nodeOffset(extra.node);
const target = sema.mod.getTarget();
if (!target.isWasm()) {
return sema.fail(block, builtin_src, "builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
@@ -26248,9 +26118,9 @@ fn zirWasmMemoryGrow(
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
- const builtin_src = LazySrcLoc.nodeOffset(extra.node);
- const index_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const delta_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
+ const builtin_src = block.nodeOffset(extra.node);
+ const index_src = block.builtinCallArgSrc(extra.node, 0);
+ const delta_src = block.builtinCallArgSrc(extra.node, 1);
const target = sema.mod.getTarget();
if (!target.isWasm()) {
return sema.fail(block, builtin_src, "builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is {s}", .{@tagName(target.cpu.arch)});
@@ -26283,9 +26153,9 @@ fn resolvePrefetchOptions(
const options_ty = try sema.getBuiltinType("PrefetchOptions");
const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
- const rw_src = sema.maybeOptionsSrc(block, src, "rw");
- const locality_src = sema.maybeOptionsSrc(block, src, "locality");
- const cache_src = sema.maybeOptionsSrc(block, src, "cache");
+ const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
+ const locality_src = block.src(.{ .init_field_locality = src.offset.node_offset_builtin_call_arg.builtin_call_node });
+ const cache_src = block.src(.{ .init_field_cache = src.offset.node_offset_builtin_call_arg.builtin_call_node });
const rw = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "rw", .no_embedded_nulls), rw_src);
const rw_val = try sema.resolveConstDefinedValue(block, rw_src, rw, .{
@@ -26315,18 +26185,12 @@ fn zirPrefetch(
extended: Zir.Inst.Extended.InstData,
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
- const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const opts_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
+ const ptr_src = block.builtinCallArgSrc(extra.node, 0);
+ const opts_src = block.builtinCallArgSrc(extra.node, 1);
const ptr = try sema.resolveInst(extra.lhs);
try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));
- const options = sema.resolvePrefetchOptions(block, .unneeded, extra.rhs) catch |err| switch (err) {
- error.NeededSourceLocation => {
- _ = try sema.resolvePrefetchOptions(block, opts_src, extra.rhs);
- unreachable;
- },
- else => |e| return e,
- };
+ const options = try sema.resolvePrefetchOptions(block, opts_src, extra.rhs);
if (!block.is_comptime) {
_ = try block.addInst(.{
@@ -26361,10 +26225,10 @@ fn resolveExternOptions(
const extern_options_ty = try sema.getBuiltinType("ExternOptions");
const options = try sema.coerce(block, extern_options_ty, options_inst, src);
- const name_src = sema.maybeOptionsSrc(block, src, "name");
- const library_src = sema.maybeOptionsSrc(block, src, "library");
- const linkage_src = sema.maybeOptionsSrc(block, src, "linkage");
- const thread_local_src = sema.maybeOptionsSrc(block, src, "thread_local");
+ const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
+ const library_src = block.src(.{ .init_field_library = src.offset.node_offset_builtin_call_arg.builtin_call_node });
+ const linkage_src = block.src(.{ .init_field_linkage = src.offset.node_offset_builtin_call_arg.builtin_call_node });
+ const thread_local_src = block.src(.{ .init_field_thread_local = src.offset.node_offset_builtin_call_arg.builtin_call_node });
const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name", .no_embedded_nulls), name_src);
const name = try sema.toConstString(block, name_src, name_ref, .{
@@ -26422,8 +26286,8 @@ fn zirBuiltinExtern(
const mod = sema.mod;
const ip = &mod.intern_pool;
const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
- const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
+ const ty_src = block.builtinCallArgSrc(extra.node, 0);
+ const options_src = block.builtinCallArgSrc(extra.node, 1);
var ty = try sema.resolveType(block, ty_src, extra.lhs);
if (!ty.isPtrAtRuntime(mod)) {
@@ -26431,29 +26295,22 @@ fn zirBuiltinExtern(
}
if (!try sema.validateExternType(ty, .other)) {
const msg = msg: {
- const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
+ const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- const src_decl = sema.mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(ty_src, mod), ty, .other);
+ try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other);
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
}
- const options = sema.resolveExternOptions(block, .unneeded, extra.rhs) catch |err| switch (err) {
- error.NeededSourceLocation => {
- _ = try sema.resolveExternOptions(block, options_src, extra.rhs);
- unreachable;
- },
- else => |e| return e,
- };
+ const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
if (options.linkage == .weak and !ty.ptrAllowsZero(mod)) {
ty = try mod.optionalType(ty.toIntern());
}
const ptr_info = ty.ptrInfo(mod);
- const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node);
+ const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace);
errdefer mod.destroyDecl(new_decl_index);
const new_decl = mod.declPtr(new_decl_index);
try mod.initNewAnonDecl(
@@ -26503,8 +26360,8 @@ fn zirWorkItem(
zir_tag: Zir.Inst.Extended,
) CompileError!Air.Inst.Ref {
const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
- const dimension_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
- const builtin_src = LazySrcLoc.nodeOffset(extra.node);
+ const dimension_src = block.builtinCallArgSrc(extra.node, 0);
+ const builtin_src = block.nodeOffset(extra.node);
const target = sema.mod.getTarget();
switch (target.cpu.arch) {
@@ -26545,11 +26402,11 @@ fn zirInComptime(
fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src: ?LazySrcLoc) !void {
if (block.is_comptime) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "unable to evaluate comptime expression", .{});
+ const msg = try sema.errMsg(src, "unable to evaluate comptime expression", .{});
errdefer msg.destroy(sema.gpa);
if (runtime_src) |some| {
- try sema.errNote(block, some, msg, "operation is runtime due to this operand", .{});
+ try sema.errNote(some, msg, "operation is runtime due to this operand", .{});
}
if (block.comptime_reason) |some| {
try some.explain(sema, msg);
@@ -26572,10 +26429,9 @@ fn validateVarType(
if (is_extern) {
if (!try sema.validateExternType(var_ty, .other)) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "extern variable cannot have type '{}'", .{var_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "extern variable cannot have type '{}'", .{var_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(src, mod), var_ty, .other);
+ try sema.explainWhyTypeIsNotExtern(msg, src, var_ty, .other);
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -26594,13 +26450,12 @@ fn validateVarType(
if (!try sema.typeRequiresComptime(var_ty)) return;
const msg = msg: {
- const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)});
+ const msg = try sema.errMsg(src, "variable of type '{}' must be const or comptime", .{var_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsComptime(msg, src_decl.toSrcLoc(src, mod), var_ty);
+ try sema.explainWhyTypeIsComptime(msg, src, var_ty);
if (var_ty.zigTypeTag(mod) == .ComptimeInt or var_ty.zigTypeTag(mod) == .ComptimeFloat) {
- try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});
+ try sema.errNote(src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{});
}
break :msg msg;
@@ -26613,7 +26468,7 @@ const TypeSet = std.AutoHashMapUnmanaged(InternPool.Index, void);
fn explainWhyTypeIsComptime(
sema: *Sema,
msg: *Module.ErrorMsg,
- src_loc: Module.SrcLoc,
+ src_loc: LazySrcLoc,
ty: Type,
) CompileError!void {
var type_set = TypeSet{};
@@ -26626,7 +26481,7 @@ fn explainWhyTypeIsComptime(
fn explainWhyTypeIsComptimeInner(
sema: *Sema,
msg: *Module.ErrorMsg,
- src_loc: Module.SrcLoc,
+ src_loc: LazySrcLoc,
ty: Type,
type_set: *TypeSet,
) CompileError!void {
@@ -26644,13 +26499,13 @@ fn explainWhyTypeIsComptimeInner(
=> return,
.Fn => {
- try mod.errNoteNonLazy(src_loc, msg, "use '*const {}' for a function pointer type", .{
+ try sema.errNote(src_loc, msg, "use '*const {}' for a function pointer type", .{
ty.fmt(sema.mod),
});
},
.Type => {
- try mod.errNoteNonLazy(src_loc, msg, "types are not available at runtime", .{});
+ try sema.errNote(src_loc, msg, "types are not available at runtime", .{});
},
.ComptimeFloat,
@@ -26662,7 +26517,7 @@ fn explainWhyTypeIsComptimeInner(
=> return,
.Opaque => {
- try mod.errNoteNonLazy(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(sema.mod)});
+ try sema.errNote(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(sema.mod)});
},
.Array, .Vector => {
@@ -26673,14 +26528,14 @@ fn explainWhyTypeIsComptimeInner(
if (elem_ty.zigTypeTag(mod) == .Fn) {
const fn_info = mod.typeToFunc(elem_ty).?;
if (fn_info.is_generic) {
- try mod.errNoteNonLazy(src_loc, msg, "function is generic", .{});
+ try sema.errNote(src_loc, msg, "function is generic", .{});
}
switch (fn_info.cc) {
- .Inline => try mod.errNoteNonLazy(src_loc, msg, "function has inline calling convention", .{}),
+ .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}),
else => {},
}
if (Type.fromInterned(fn_info.return_type).comptimeOnly(mod)) {
- try mod.errNoteNonLazy(src_loc, msg, "function has a comptime-only return type", .{});
+ try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{});
}
return;
}
@@ -26700,14 +26555,14 @@ fn explainWhyTypeIsComptimeInner(
if (mod.typeToStruct(ty)) |struct_type| {
for (0..struct_type.field_types.len) |i| {
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
- const field_src_loc = mod.fieldSrcLoc(struct_type.decl.unwrap().?, .{
- .index = i,
- .range = .type,
- });
+ const field_src: LazySrcLoc = .{
+ .base_node_inst = struct_type.zir_index.unwrap().?,
+ .offset = .{ .container_field_type = @intCast(i) },
+ };
if (try sema.typeRequiresComptime(field_ty)) {
- try mod.errNoteNonLazy(field_src_loc, msg, "struct requires comptime because of this field", .{});
- try sema.explainWhyTypeIsComptimeInner(msg, field_src_loc, field_ty, type_set);
+ try sema.errNote(field_src, msg, "struct requires comptime because of this field", .{});
+ try sema.explainWhyTypeIsComptimeInner(msg, field_src, field_ty, type_set);
}
}
}
@@ -26720,14 +26575,14 @@ fn explainWhyTypeIsComptimeInner(
if (mod.typeToUnion(ty)) |union_obj| {
for (0..union_obj.field_types.len) |i| {
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[i]);
- const field_src_loc = mod.fieldSrcLoc(union_obj.decl, .{
- .index = i,
- .range = .type,
- });
+ const field_src: LazySrcLoc = .{
+ .base_node_inst = union_obj.zir_index,
+ .offset = .{ .container_field_type = @intCast(i) },
+ };
if (try sema.typeRequiresComptime(field_ty)) {
- try mod.errNoteNonLazy(field_src_loc, msg, "union requires comptime because of this field", .{});
- try sema.explainWhyTypeIsComptimeInner(msg, field_src_loc, field_ty, type_set);
+ try sema.errNote(field_src, msg, "union requires comptime because of this field", .{});
+ try sema.explainWhyTypeIsComptimeInner(msg, field_src, field_ty, type_set);
}
}
}
@@ -26817,7 +26672,7 @@ fn validateExternType(
fn explainWhyTypeIsNotExtern(
sema: *Sema,
msg: *Module.ErrorMsg,
- src_loc: Module.SrcLoc,
+ src_loc: LazySrcLoc,
ty: Type,
position: ExternPosition,
) CompileError!void {
@@ -26842,55 +26697,55 @@ fn explainWhyTypeIsNotExtern(
.Pointer => {
if (ty.isSlice(mod)) {
- try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
+ try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
} else {
const pointee_ty = ty.childType(mod);
if (!ty.isConstPtr(mod) and pointee_ty.zigTypeTag(mod) == .Fn) {
- try mod.errNoteNonLazy(src_loc, msg, "pointer to extern function must be 'const'", .{});
+ try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{});
} else if (try sema.typeRequiresComptime(ty)) {
- try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
+ try sema.errNote(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)});
try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
}
try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other);
}
},
- .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
- .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
+ .Void => try sema.errNote(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
+ .NoReturn => try sema.errNote(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
.Int => if (!std.math.isPowerOfTwo(ty.intInfo(mod).bits)) {
- try mod.errNoteNonLazy(src_loc, msg, "only integers with 0 or power of two bits are extern compatible", .{});
+ try sema.errNote(src_loc, msg, "only integers with 0 or power of two bits are extern compatible", .{});
} else {
- try mod.errNoteNonLazy(src_loc, msg, "only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible", .{});
+ try sema.errNote(src_loc, msg, "only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible", .{});
},
.Fn => {
if (position != .other) {
- try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{});
- try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{});
+ try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{});
+ try sema.errNote(src_loc, msg, "use '*const ' to make a function pointer type", .{});
return;
}
switch (ty.fnCallingConvention(mod)) {
- .Unspecified => try mod.errNoteNonLazy(src_loc, msg, "extern function must specify calling convention", .{}),
- .Async => try mod.errNoteNonLazy(src_loc, msg, "async function cannot be extern", .{}),
- .Inline => try mod.errNoteNonLazy(src_loc, msg, "inline function cannot be extern", .{}),
+ .Unspecified => try sema.errNote(src_loc, msg, "extern function must specify calling convention", .{}),
+ .Async => try sema.errNote(src_loc, msg, "async function cannot be extern", .{}),
+ .Inline => try sema.errNote(src_loc, msg, "inline function cannot be extern", .{}),
else => return,
}
},
.Enum => {
const tag_ty = ty.intTagType(mod);
- try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});
+ try sema.errNote(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});
try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
},
- .Struct => try mod.errNoteNonLazy(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),
- .Union => try mod.errNoteNonLazy(src_loc, msg, "only extern unions and ABI sized packed unions are extern compatible", .{}),
+ .Struct => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),
+ .Union => try sema.errNote(src_loc, msg, "only extern unions and ABI sized packed unions are extern compatible", .{}),
.Array => {
if (position == .ret_ty) {
- return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a return type", .{});
+ return sema.errNote(src_loc, msg, "arrays are not allowed as a return type", .{});
} else if (position == .param_ty) {
- return mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});
+ return sema.errNote(src_loc, msg, "arrays are not allowed as a parameter type", .{});
}
try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(mod), .element);
},
.Vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(mod), .element),
- .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}),
+ .Optional => try sema.errNote(src_loc, msg, "only pointer like optionals are extern compatible", .{}),
}
}
@@ -26933,7 +26788,7 @@ fn validatePackedType(sema: *Sema, ty: Type) !bool {
fn explainWhyTypeIsNotPacked(
sema: *Sema,
msg: *Module.ErrorMsg,
- src_loc: Module.SrcLoc,
+ src_loc: LazySrcLoc,
ty: Type,
) CompileError!void {
const mod = sema.mod;
@@ -26959,19 +26814,19 @@ fn explainWhyTypeIsNotPacked(
.AnyFrame,
.Optional,
.Array,
- => try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{}),
+ => try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{}),
.Pointer => if (ty.isSlice(mod)) {
- try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
+ try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
} else {
- try mod.errNoteNonLazy(src_loc, msg, "comptime-only pointer has no guaranteed in-memory representation", .{});
+ try sema.errNote(src_loc, msg, "comptime-only pointer has no guaranteed in-memory representation", .{});
try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
},
.Fn => {
- try mod.errNoteNonLazy(src_loc, msg, "type has no guaranteed in-memory representation", .{});
- try mod.errNoteNonLazy(src_loc, msg, "use '*const ' to make a function pointer type", .{});
+ try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{});
+ try sema.errNote(src_loc, msg, "use '*const ' to make a function pointer type", .{});
},
- .Struct => try mod.errNoteNonLazy(src_loc, msg, "only packed structs layout are allowed in packed types", .{}),
- .Union => try mod.errNoteNonLazy(src_loc, msg, "only packed unions layout are allowed in packed types", .{}),
+ .Struct => try sema.errNote(src_loc, msg, "only packed structs layout are allowed in packed types", .{}),
+ .Union => try sema.errNote(src_loc, msg, "only packed unions layout are allowed in packed types", .{}),
}
}
@@ -27022,11 +26877,11 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP
const panic_messages_ty = try sema.getBuiltinType("panic_messages");
const msg_decl_index = (sema.namespaceLookup(
block,
- .unneeded,
+ LazySrcLoc.unneeded,
panic_messages_ty.getNamespaceIndex(mod),
try mod.intern_pool.getOrPutString(gpa, @tagName(panic_id), .no_embedded_nulls),
) catch |err| switch (err) {
- error.AnalysisFail, error.NeededSourceLocation => @panic("std.builtin.panic_messages is corrupt"),
+ error.AnalysisFail => @panic("std.builtin.panic_messages is corrupt"),
error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
error.OutOfMemory => |e| return e,
}).?;
@@ -27053,6 +26908,7 @@ fn addSafetyCheck(
.instructions = .{},
.inlining = parent_block.inlining,
.is_comptime = false,
+ .src_base_inst = parent_block.src_base_inst,
};
defer fail_block.instructions.deinit(gpa);
@@ -27161,6 +27017,7 @@ fn panicUnwrapError(
.instructions = .{},
.inlining = parent_block.inlining,
.is_comptime = false,
+ .src_base_inst = parent_block.src_base_inst,
};
defer fail_block.instructions.deinit(gpa);
@@ -27277,6 +27134,7 @@ fn safetyCheckFormatted(
.instructions = .{},
.inlining = parent_block.inlining,
.is_comptime = false,
+ .src_base_inst = parent_block.src_base_inst,
};
defer fail_block.instructions.deinit(gpa);
@@ -27300,13 +27158,11 @@ fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
sema.branch_count += 1;
if (sema.branch_count > sema.branch_quota) {
const msg = try sema.errMsg(
- block,
src,
"evaluation exceeded {d} backwards branches",
.{sema.branch_quota},
);
try sema.errNote(
- block,
src,
msg,
"use @setEvalBranchQuota() to raise the branch limit from {d}",
@@ -27472,10 +27328,10 @@ fn fieldVal(
},
else => {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "type '{}' has no members", .{child_type.fmt(mod)});
+ const msg = try sema.errMsg(src, "type '{}' has no members", .{child_type.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- if (child_type.isSlice(mod)) try sema.errNote(block, src, msg, "slice values have 'len' and 'ptr' members", .{});
- if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(block, src, msg, "array values have 'len' member", .{});
+ if (child_type.isSlice(mod)) try sema.errNote(src, msg, "slice values have 'len' and 'ptr' members", .{});
+ if (child_type.zigTypeTag(mod) == .Array) try sema.errNote(src, msg, "array values have 'len' member", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -27633,7 +27489,7 @@ fn fieldPtr(
}
},
.Type => {
- _ = try sema.resolveConstDefinedValue(block, .unneeded, object_ptr, undefined);
+ _ = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, object_ptr, undefined);
const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
const inner = if (is_pointer_to)
try sema.analyzeLoad(block, src, result, object_ptr_src)
@@ -27885,7 +27741,7 @@ fn fieldCallBind(
};
const msg = msg: {
- const msg = try sema.errMsg(block, src, "no field or member function named '{}' in '{}'", .{
+ const msg = try sema.errMsg(src, "no field or member function named '{}' in '{}'", .{
field_name.fmt(ip),
concrete_ty.fmt(mod),
});
@@ -27893,10 +27749,13 @@ fn fieldCallBind(
try sema.addDeclaredHereNote(msg, concrete_ty);
if (found_decl) |decl_idx| {
const decl = mod.declPtr(decl_idx);
- try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "'{}' is not a member function", .{field_name.fmt(ip)});
+ try sema.errNote(.{
+ .base_node_inst = decl.zir_decl_index.unwrap().?,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ }, msg, "'{}' is not a member function", .{field_name.fmt(ip)});
}
if (concrete_ty.zigTypeTag(mod) == .ErrorUnion) {
- try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{});
+ try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
}
break :msg msg;
};
@@ -27954,11 +27813,14 @@ fn namespaceLookup(
const decl = mod.declPtr(decl_index);
if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "'{}' is not marked 'pub'", .{
+ const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{
decl_name.fmt(&mod.intern_pool),
});
errdefer msg.destroy(gpa);
- try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "declared here", .{});
+ try sema.errNote(.{
+ .base_node_inst = decl.zir_decl_index.unwrap().?,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ }, msg, "declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -28023,7 +27885,7 @@ fn structFieldPtr(
const struct_type = mod.typeToStruct(struct_ty).?;
const field_index = struct_type.nameIndex(ip, field_name) orelse
- return sema.failWithBadStructFieldAccess(block, struct_type, field_name_src, field_name);
+ return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, field_name_src, struct_ty, initializing);
}
@@ -28138,7 +28000,7 @@ fn structFieldVal(
return sema.tupleFieldVal(block, src, struct_byval, field_name, field_name_src, struct_ty);
const field_index = struct_type.nameIndex(ip, field_name) orelse
- return sema.failWithBadStructFieldAccess(block, struct_type, field_name_src, field_name);
+ return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
if (struct_type.fieldIsComptime(ip, field_index)) {
try sema.resolveStructFieldInits(struct_ty);
return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
@@ -28291,7 +28153,7 @@ fn unionFieldPtr(
if (initializing and field_ty.zigTypeTag(mod) == .NoReturn) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
+ const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{});
errdefer msg.destroy(sema.gpa);
try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' declared here", .{
@@ -28324,7 +28186,7 @@ fn unionFieldPtr(
const msg = msg: {
const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), mod).?;
const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, mod);
- const msg = try sema.errMsg(block, src, "access of union field '{}' while field '{}' is active", .{
+ const msg = try sema.errMsg(src, "access of union field '{}' while field '{}' is active", .{
field_name.fmt(ip),
active_field_name.fmt(ip),
});
@@ -28392,7 +28254,7 @@ fn unionFieldVal(
const msg = msg: {
const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, zcu);
- const msg = try sema.errMsg(block, src, "access of union field '{}' while field '{}' is active", .{
+ const msg = try sema.errMsg(src, "access of union field '{}' while field '{}' is active", .{
field_name.fmt(ip), active_field_name.fmt(ip),
});
errdefer msg.destroy(sema.gpa);
@@ -28615,15 +28477,13 @@ fn validateRuntimeElemAccess(
if (try sema.typeRequiresComptime(elem_ty)) {
const msg = msg: {
const msg = try sema.errMsg(
- block,
elem_index_src,
"values of type '{}' must be comptime-known, but index value is runtime-known",
.{parent_ty.fmt(mod)},
);
errdefer msg.destroy(sema.gpa);
- const src_decl = mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsComptime(msg, src_decl.toSrcLoc(parent_src, mod), parent_ty);
+ try sema.explainWhyTypeIsComptime(msg, parent_src, parent_ty);
break :msg msg;
};
@@ -29011,21 +28871,18 @@ const CoerceOpts = struct {
func_inst: Air.Inst.Ref = .none,
param_i: u32 = undefined,
- fn get(info: @This(), sema: *Sema) !?Module.SrcLoc {
+ fn get(info: @This(), sema: *Sema) !?LazySrcLoc {
if (info.func_inst == .none) return null;
- const mod = sema.mod;
- const fn_decl = (try sema.funcDeclSrc(info.func_inst)) orelse return null;
- const param_src = Module.paramSrc(0, mod, fn_decl, info.param_i);
- if (param_src == .node_offset_param) {
- return Module.SrcLoc{
- .file_scope = fn_decl.getFileScope(mod),
- .parent_decl_node = fn_decl.src_node,
- .lazy = LazySrcLoc.nodeOffset(param_src.node_offset_param),
- };
- }
- return fn_decl.toSrcLoc(param_src, mod);
+ const fn_decl = try sema.funcDeclSrc(info.func_inst) orelse return null;
+ return .{
+ .base_node_inst = fn_decl.zir_decl_index.unwrap().?,
+ .offset = .{ .fn_proto_param_type = .{
+ .fn_proto_node_offset = 0,
+ .param_index = info.param_i,
+ } },
+ };
}
- } = .{},
+ } = .{ .func_inst = .none, .param_i = undefined },
};
fn coerceExtra(
@@ -29118,7 +28975,7 @@ fn coerceExtra(
// Function body to function pointer.
if (inst_ty.zigTypeTag(zcu) == .Fn) {
- const fn_val = try sema.resolveConstDefinedValue(block, .unneeded, inst, undefined);
+ const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
const fn_decl = fn_val.pointerDecl(zcu).?;
const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);
return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
@@ -29366,9 +29223,9 @@ fn coerceExtra(
// pointer to tuple to slice
if (!dest_info.flags.is_const) {
const err_msg = err_msg: {
- const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(zcu)});
+ const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(zcu)});
errdefer err_msg.destroy(sema.gpa);
- try sema.errNote(block, dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{});
+ try sema.errNote(dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{});
break :err_msg err_msg;
};
return sema.failWithOwnedErrorMsg(block, err_msg);
@@ -29455,7 +29312,7 @@ fn coerceExtra(
},
.Float, .ComptimeFloat => switch (inst_ty.zigTypeTag(zcu)) {
.ComptimeFloat => {
- const val = try sema.resolveConstDefinedValue(block, .unneeded, inst, undefined);
+ const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
const result_val = try val.floatCast(dest_ty, zcu);
return Air.internedToRef(result_val.toIntern());
},
@@ -29514,7 +29371,7 @@ fn coerceExtra(
.Enum => switch (inst_ty.zigTypeTag(zcu)) {
.EnumLiteral => {
// enum literal to enum
- const val = try sema.resolveConstDefinedValue(block, .unneeded, inst, undefined);
+ const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;
const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {
return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{
@@ -29648,54 +29505,58 @@ fn coerceExtra(
if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .NoReturn) {
const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "function declared 'noreturn' returns", .{});
+ const msg = try sema.errMsg(inst_src, "function declared 'noreturn' returns", .{});
errdefer msg.destroy(sema.gpa);
- const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
- const src_decl = zcu.funcOwnerDeclPtr(sema.func_index);
- try zcu.errNoteNonLazy(src_decl.toSrcLoc(ret_ty_src, zcu), msg, "'noreturn' declared here", .{});
+ const ret_ty_src: LazySrcLoc = .{
+ .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,
+ .offset = .{ .node_offset_fn_type_ret_ty = 0 },
+ };
+ try sema.errNote(ret_ty_src, msg, "'noreturn' declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
}
const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(zcu), inst_ty.fmt(zcu) });
+ const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(zcu), inst_ty.fmt(zcu) });
errdefer msg.destroy(sema.gpa);
// E!T to T
if (inst_ty.zigTypeTag(zcu) == .ErrorUnion and
(try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
{
- try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});
- try sema.errNote(block, inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
+ try sema.errNote(inst_src, msg, "cannot convert error union to payload type", .{});
+ try sema.errNote(inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
}
// ?T to T
if (inst_ty.zigTypeTag(zcu) == .Optional and
(try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(zcu), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
{
- try sema.errNote(block, inst_src, msg, "cannot convert optional to payload type", .{});
- try sema.errNote(block, inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});
+ try sema.errNote(inst_src, msg, "cannot convert optional to payload type", .{});
+ try sema.errNote(inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});
}
- try in_memory_result.report(sema, block, inst_src, msg);
+ try in_memory_result.report(sema, inst_src, msg);
// Add notes about function return type
if (opts.is_ret and
zcu.test_functions.get(zcu.funcOwnerDeclIndex(sema.func_index)) == null)
{
- const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
- const src_decl = zcu.funcOwnerDeclPtr(sema.func_index);
+ const ret_ty_src: LazySrcLoc = .{
+ .base_node_inst = zcu.funcOwnerDeclPtr(sema.func_index).zir_decl_index.unwrap().?,
+ .offset = .{ .node_offset_fn_type_ret_ty = 0 },
+ };
if (inst_ty.isError(zcu) and !dest_ty.isError(zcu)) {
- try zcu.errNoteNonLazy(src_decl.toSrcLoc(ret_ty_src, zcu), msg, "function cannot return an error", .{});
+ try sema.errNote(ret_ty_src, msg, "function cannot return an error", .{});
} else {
- try zcu.errNoteNonLazy(src_decl.toSrcLoc(ret_ty_src, zcu), msg, "function return type declared here", .{});
+ try sema.errNote(ret_ty_src, msg, "function return type declared here", .{});
}
}
if (try opts.param_src.get(sema)) |param_src| {
- try zcu.errNoteNonLazy(param_src, msg, "parameter type declared here", .{});
+ try sema.errNote(param_src, msg, "parameter type declared here", .{});
}
// TODO maybe add "cannot store an error in type '{}'" note
@@ -29830,7 +29691,7 @@ const InMemoryCoercionResult = union(enum) {
return res;
}
- fn report(res: *const InMemoryCoercionResult, sema: *Sema, block: *Block, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {
+ fn report(res: *const InMemoryCoercionResult, sema: *Sema, src: LazySrcLoc, msg: *Module.ErrorMsg) !void {
const mod = sema.mod;
var cur = res;
while (true) switch (cur.*) {
@@ -29841,93 +29702,93 @@ const InMemoryCoercionResult = union(enum) {
break;
},
.int_not_coercible => |int| {
- try sema.errNote(block, src, msg, "{s} {d}-bit int cannot represent all possible {s} {d}-bit values", .{
+ try sema.errNote(src, msg, "{s} {d}-bit int cannot represent all possible {s} {d}-bit values", .{
@tagName(int.wanted_signedness), int.wanted_bits, @tagName(int.actual_signedness), int.actual_bits,
});
break;
},
.error_union_payload => |pair| {
- try sema.errNote(block, src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{
+ try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
cur = pair.child;
},
.array_len => |lens| {
- try sema.errNote(block, src, msg, "array of length {d} cannot cast into an array of length {d}", .{
+ try sema.errNote(src, msg, "array of length {d} cannot cast into an array of length {d}", .{
lens.actual, lens.wanted,
});
break;
},
.array_sentinel => |sentinel| {
if (sentinel.actual.toIntern() != .unreachable_value) {
- try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
+ try sema.errNote(src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
sentinel.actual.fmtValue(mod, sema), sentinel.wanted.fmtValue(mod, sema),
});
} else {
- try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{
+ try sema.errNote(src, msg, "destination array requires '{}' sentinel", .{
sentinel.wanted.fmtValue(mod, sema),
});
}
break;
},
.array_elem => |pair| {
- try sema.errNote(block, src, msg, "array element type '{}' cannot cast into array element type '{}'", .{
+ try sema.errNote(src, msg, "array element type '{}' cannot cast into array element type '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
cur = pair.child;
},
.vector_len => |lens| {
- try sema.errNote(block, src, msg, "vector of length {d} cannot cast into a vector of length {d}", .{
+ try sema.errNote(src, msg, "vector of length {d} cannot cast into a vector of length {d}", .{
lens.actual, lens.wanted,
});
break;
},
.vector_elem => |pair| {
- try sema.errNote(block, src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{
+ try sema.errNote(src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
cur = pair.child;
},
.optional_shape => |pair| {
- try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
+ try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
pair.actual.optionalChild(mod).fmt(mod), pair.wanted.optionalChild(mod).fmt(mod),
});
break;
},
.optional_child => |pair| {
- try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
+ try sema.errNote(src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
cur = pair.child;
},
.from_anyerror => {
- try sema.errNote(block, src, msg, "global error set cannot cast into a smaller set", .{});
+ try sema.errNote(src, msg, "global error set cannot cast into a smaller set", .{});
break;
},
.missing_error => |missing_errors| {
for (missing_errors) |err| {
- try sema.errNote(block, src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&mod.intern_pool)});
+ try sema.errNote(src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&mod.intern_pool)});
}
break;
},
.fn_var_args => |wanted_var_args| {
if (wanted_var_args) {
- try sema.errNote(block, src, msg, "non-variadic function cannot cast into a variadic function", .{});
+ try sema.errNote(src, msg, "non-variadic function cannot cast into a variadic function", .{});
} else {
- try sema.errNote(block, src, msg, "variadic function cannot cast into a non-variadic function", .{});
+ try sema.errNote(src, msg, "variadic function cannot cast into a non-variadic function", .{});
}
break;
},
.fn_generic => |wanted_generic| {
if (wanted_generic) {
- try sema.errNote(block, src, msg, "non-generic function cannot cast into a generic function", .{});
+ try sema.errNote(src, msg, "non-generic function cannot cast into a generic function", .{});
} else {
- try sema.errNote(block, src, msg, "generic function cannot cast into a non-generic function", .{});
+ try sema.errNote(src, msg, "generic function cannot cast into a non-generic function", .{});
}
break;
},
.fn_param_count => |lens| {
- try sema.errNote(block, src, msg, "function with {d} parameters cannot cast into a function with {d} parameters", .{
+ try sema.errNote(src, msg, "function with {d} parameters cannot cast into a function with {d} parameters", .{
lens.actual, lens.wanted,
});
break;
@@ -29944,69 +29805,69 @@ const InMemoryCoercionResult = union(enum) {
}
}
if (!actual_noalias) {
- try sema.errNote(block, src, msg, "regular parameter {d} cannot cast into a noalias parameter", .{index});
+ try sema.errNote(src, msg, "regular parameter {d} cannot cast into a noalias parameter", .{index});
} else {
- try sema.errNote(block, src, msg, "noalias parameter {d} cannot cast into a regular parameter", .{index});
+ try sema.errNote(src, msg, "noalias parameter {d} cannot cast into a regular parameter", .{index});
}
break;
},
.fn_param_comptime => |param| {
if (param.wanted) {
- try sema.errNote(block, src, msg, "non-comptime parameter {d} cannot cast into a comptime parameter", .{param.index});
+ try sema.errNote(src, msg, "non-comptime parameter {d} cannot cast into a comptime parameter", .{param.index});
} else {
- try sema.errNote(block, src, msg, "comptime parameter {d} cannot cast into a non-comptime parameter", .{param.index});
+ try sema.errNote(src, msg, "comptime parameter {d} cannot cast into a non-comptime parameter", .{param.index});
}
break;
},
.fn_param => |param| {
- try sema.errNote(block, src, msg, "parameter {d} '{}' cannot cast into '{}'", .{
+ try sema.errNote(src, msg, "parameter {d} '{}' cannot cast into '{}'", .{
param.index, param.actual.fmt(mod), param.wanted.fmt(mod),
});
cur = param.child;
},
.fn_cc => |cc| {
- try sema.errNote(block, src, msg, "calling convention '{s}' cannot cast into calling convention '{s}'", .{ @tagName(cc.actual), @tagName(cc.wanted) });
+ try sema.errNote(src, msg, "calling convention '{s}' cannot cast into calling convention '{s}'", .{ @tagName(cc.actual), @tagName(cc.wanted) });
break;
},
.fn_return_type => |pair| {
- try sema.errNote(block, src, msg, "return type '{}' cannot cast into return type '{}'", .{
+ try sema.errNote(src, msg, "return type '{}' cannot cast into return type '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
cur = pair.child;
},
.ptr_child => |pair| {
- try sema.errNote(block, src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{
+ try sema.errNote(src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
cur = pair.child;
},
.ptr_addrspace => |@"addrspace"| {
- try sema.errNote(block, src, msg, "address space '{s}' cannot cast into address space '{s}'", .{ @tagName(@"addrspace".actual), @tagName(@"addrspace".wanted) });
+ try sema.errNote(src, msg, "address space '{s}' cannot cast into address space '{s}'", .{ @tagName(@"addrspace".actual), @tagName(@"addrspace".wanted) });
break;
},
.ptr_sentinel => |sentinel| {
if (sentinel.actual.toIntern() != .unreachable_value) {
- try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
+ try sema.errNote(src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
sentinel.actual.fmtValue(mod, sema), sentinel.wanted.fmtValue(mod, sema),
});
} else {
- try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{
+ try sema.errNote(src, msg, "destination pointer requires '{}' sentinel", .{
sentinel.wanted.fmtValue(mod, sema),
});
}
break;
},
.ptr_size => |size| {
- try sema.errNote(block, src, msg, "a {s} pointer cannot cast into a {s} pointer", .{ pointerSizeString(size.actual), pointerSizeString(size.wanted) });
+ try sema.errNote(src, msg, "a {s} pointer cannot cast into a {s} pointer", .{ pointerSizeString(size.actual), pointerSizeString(size.wanted) });
break;
},
.ptr_qualifiers => |qualifiers| {
const ok_const = !qualifiers.actual_const or qualifiers.wanted_const;
const ok_volatile = !qualifiers.actual_volatile or qualifiers.wanted_volatile;
if (!ok_const) {
- try sema.errNote(block, src, msg, "cast discards const qualifier", .{});
+ try sema.errNote(src, msg, "cast discards const qualifier", .{});
} else if (!ok_volatile) {
- try sema.errNote(block, src, msg, "cast discards volatile qualifier", .{});
+ try sema.errNote(src, msg, "cast discards volatile qualifier", .{});
}
break;
},
@@ -30014,11 +29875,11 @@ const InMemoryCoercionResult = union(enum) {
const wanted_allow_zero = pair.wanted.ptrAllowsZero(mod);
const actual_allow_zero = pair.actual.ptrAllowsZero(mod);
if (actual_allow_zero and !wanted_allow_zero) {
- try sema.errNote(block, src, msg, "'{}' could have null values which are illegal in type '{}'", .{
+ try sema.errNote(src, msg, "'{}' could have null values which are illegal in type '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
} else {
- try sema.errNote(block, src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{
+ try sema.errNote(src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
}
@@ -30026,34 +29887,34 @@ const InMemoryCoercionResult = union(enum) {
},
.ptr_bit_range => |bit_range| {
if (bit_range.actual_host != bit_range.wanted_host) {
- try sema.errNote(block, src, msg, "pointer host size '{}' cannot cast into pointer host size '{}'", .{
+ try sema.errNote(src, msg, "pointer host size '{}' cannot cast into pointer host size '{}'", .{
bit_range.actual_host, bit_range.wanted_host,
});
}
if (bit_range.actual_offset != bit_range.wanted_offset) {
- try sema.errNote(block, src, msg, "pointer bit offset '{}' cannot cast into pointer bit offset '{}'", .{
+ try sema.errNote(src, msg, "pointer bit offset '{}' cannot cast into pointer bit offset '{}'", .{
bit_range.actual_offset, bit_range.wanted_offset,
});
}
break;
},
.ptr_alignment => |pair| {
- try sema.errNote(block, src, msg, "pointer alignment '{d}' cannot cast into pointer alignment '{d}'", .{
+ try sema.errNote(src, msg, "pointer alignment '{d}' cannot cast into pointer alignment '{d}'", .{
pair.actual.toByteUnits() orelse 0, pair.wanted.toByteUnits() orelse 0,
});
break;
},
.double_ptr_to_anyopaque => |pair| {
- try sema.errNote(block, src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{
+ try sema.errNote(src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
break;
},
.slice_to_anyopaque => |pair| {
- try sema.errNote(block, src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{
+ try sema.errNote(src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{
pair.actual.fmt(mod), pair.wanted.fmt(mod),
});
- try sema.errNote(block, src, msg, "consider using '.ptr'", .{});
+ try sema.errNote(src, msg, "consider using '.ptr'", .{});
break;
},
};
@@ -30667,7 +30528,7 @@ fn coerceVarArgParam(
.{},
),
.Fn => fn_ptr: {
- const fn_val = try sema.resolveConstDefinedValue(block, .unneeded, inst, undefined);
+ const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
const fn_decl = fn_val.pointerDecl(mod).?;
break :fn_ptr try sema.analyzeDeclRef(fn_decl);
},
@@ -30715,11 +30576,10 @@ fn coerceVarArgParam(
const coerced_ty = sema.typeOf(coerced);
if (!try sema.validateExternType(coerced_ty, .param_ty)) {
const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(inst_src, "cannot pass '{}' to variadic function", .{coerced_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- const src_decl = sema.mod.declPtr(block.src_decl);
- try sema.explainWhyTypeIsNotExtern(msg, src_decl.toSrcLoc(inst_src, mod), coerced_ty, .param_ty);
+ try sema.explainWhyTypeIsNotExtern(msg, inst_src, coerced_ty, .param_ty);
try sema.addDeclaredHereNote(msg, coerced_ty);
break :msg msg;
@@ -30879,7 +30739,6 @@ fn checkComptimeKnownStore(sema: *Sema, block: *Block, store_inst_ref: Air.Inst.
{
try maybe_comptime_alloc.stores.append(sema.arena, .{
.inst = store_inst,
- .src_decl = block.src_decl,
.src = store_src,
});
return;
@@ -30913,8 +30772,7 @@ fn checkKnownAllocPtr(sema: *Sema, block: *Block, base_ptr: Air.Inst.Ref, new_pt
try maybe_comptime_alloc.stores.append(sema.arena, .{
.inst = new_ptr_inst,
- .src_decl = block.src_decl,
- .src = .unneeded,
+ .src = LazySrcLoc.unneeded,
});
},
.ptr_elem_ptr => {
@@ -30937,10 +30795,9 @@ fn markMaybeComptimeAllocRuntime(sema: *Sema, block: *Block, alloc_inst: Air.Ins
const maybe_comptime_alloc = (sema.maybe_comptime_allocs.fetchRemove(alloc_inst) orelse return).value;
// Since the alloc has been determined to be runtime, we must check that
// all other stores to it are permitted to be runtime values.
- const mod = sema.mod;
const slice = maybe_comptime_alloc.stores.slice();
- for (slice.items(.inst), slice.items(.src_decl), slice.items(.src)) |other_inst, other_src_decl, other_src| {
- if (other_src == .unneeded) {
+ for (slice.items(.inst), slice.items(.src)) |other_inst, other_src| {
+ if (other_src.offset == .unneeded) {
switch (sema.air_instructions.items(.tag)[@intFromEnum(other_inst)]) {
.set_union_tag, .optional_payload_ptr_set, .errunion_payload_ptr_set => continue,
else => unreachable, // assertion failure
@@ -30950,10 +30807,9 @@ fn markMaybeComptimeAllocRuntime(sema: *Sema, block: *Block, alloc_inst: Air.Ins
const other_operand = other_data.rhs;
if (!sema.checkRuntimeValue(other_operand)) {
return sema.failWithOwnedErrorMsg(block, msg: {
- const other_src_resolved = mod.declPtr(other_src_decl).toSrcLoc(other_src, mod);
- const msg = try Module.ErrorMsg.create(sema.gpa, other_src_resolved, "runtime value contains reference to comptime var", .{});
+ const msg = try sema.errMsg(other_src, "runtime value contains reference to comptime var", .{});
errdefer msg.destroy(sema.gpa);
- try mod.errNoteNonLazy(other_src_resolved, msg, "comptime var pointers are not available at runtime", .{});
+ try sema.errNote(other_src, msg, "comptime var pointers are not available at runtime", .{});
break :msg msg;
});
}
@@ -31215,11 +31071,11 @@ fn coerceEnumToUnion(
const tag_ty = union_ty.unionTagType(mod) orelse {
const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{
+ const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
union_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, union_ty_src, msg, "cannot coerce enum to untagged union", .{});
+ try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});
try sema.addDeclaredHereNote(msg, union_ty);
break :msg msg;
};
@@ -31239,7 +31095,7 @@ fn coerceEnumToUnion(
try sema.resolveTypeFields(field_ty);
if (field_ty.zigTypeTag(mod) == .NoReturn) {
const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{});
+ const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});
errdefer msg.destroy(sema.gpa);
const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
@@ -31254,7 +31110,7 @@ fn coerceEnumToUnion(
const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse {
const msg = msg: {
const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
- const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{
+ const msg = try sema.errMsg(inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{
inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod),
field_ty.fmt(sema.mod), field_name.fmt(ip),
});
@@ -31276,7 +31132,7 @@ fn coerceEnumToUnion(
if (tag_ty.isNonexhaustiveEnum(mod)) {
const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{
+ const msg = try sema.errMsg(inst_src, "runtime coercion to union '{}' from non-exhaustive enum", .{
union_ty.fmt(sema.mod),
});
errdefer msg.destroy(sema.gpa);
@@ -31294,7 +31150,6 @@ fn coerceEnumToUnion(
for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {
if (Type.fromInterned(field_ty).zigTypeTag(mod) == .NoReturn) {
const err_msg = msg orelse try sema.errMsg(
- block,
inst_src,
"runtime coercion from enum '{}' to union '{}' which has a 'noreturn' field",
.{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) },
@@ -31318,7 +31173,6 @@ fn coerceEnumToUnion(
const msg = msg: {
const msg = try sema.errMsg(
- block,
inst_src,
"runtime coercion from enum '{}' to union '{}' which has non-void fields",
.{ tag_ty.fmt(sema.mod), union_ty.fmt(sema.mod) },
@@ -31377,12 +31231,10 @@ fn coerceAnonStructToUnion(
assert(field_count != 1);
const msg = msg: {
const msg = if (field_count > 1) try sema.errMsg(
- block,
inst_src,
"cannot initialize multiple union fields at once; unions can only have one active field",
.{},
) else try sema.errMsg(
- block,
inst_src,
"union initializer must initialize one field",
.{},
@@ -31459,12 +31311,12 @@ fn coerceArrayLike(
const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(mod));
if (dest_len != inst_len) {
const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{
+ const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
dest_ty.fmt(mod), inst_ty.fmt(mod),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
- try sema.errNote(block, inst_src, msg, "source has length {d}", .{inst_len});
+ try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});
+ try sema.errNote(inst_src, msg, "source has length {d}", .{inst_len});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -31546,12 +31398,12 @@ fn coerceTupleToArray(
if (dest_len != inst_len) {
const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{
+ const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{
dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod),
});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len});
- try sema.errNote(block, inst_src, msg, "source has length {d}", .{inst_len});
+ try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});
+ try sema.errNote(inst_src, msg, "source has length {d}", .{inst_len});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -31722,9 +31574,9 @@ fn coerceTupleToStruct(
const template = "missing struct field: {}";
const args = .{field_name.fmt(ip)};
if (root_msg) |msg| {
- try sema.errNote(block, field_src, msg, template, args);
+ try sema.errNote(field_src, msg, template, args);
} else {
- root_msg = try sema.errMsg(block, field_src, template, args);
+ root_msg = try sema.errMsg(field_src, template, args);
}
continue;
}
@@ -31860,18 +31712,18 @@ fn coerceTupleToTuple(
const field_name = tuple_ty.structFieldName(i, mod).unwrap() orelse {
const template = "missing tuple field: {d}";
if (root_msg) |msg| {
- try sema.errNote(block, field_src, msg, template, .{i});
+ try sema.errNote(field_src, msg, template, .{i});
} else {
- root_msg = try sema.errMsg(block, field_src, template, .{i});
+ root_msg = try sema.errMsg(field_src, template, .{i});
}
continue;
};
const template = "missing struct field: {}";
const args = .{field_name.fmt(ip)};
if (root_msg) |msg| {
- try sema.errNote(block, field_src, msg, template, args);
+ try sema.errNote(field_src, msg, template, args);
} else {
- root_msg = try sema.errMsg(block, field_src, template, args);
+ root_msg = try sema.errMsg(field_src, template, args);
}
continue;
}
@@ -31926,14 +31778,6 @@ fn addReferencedBy(
decl_index: InternPool.DeclIndex,
) !void {
if (sema.mod.comp.reference_trace == 0) return;
- if (src == .unneeded) {
- // We can't use NeededSourceLocation, since sites handling that assume it means a compile
- // error. Our long-term strategy here is to gradually transition from NeededSourceLocation
- // into having more LazySrcLoc tags. In the meantime, let release compilers just ignore this
- // reference (a slightly-incomplete error is better than a crash!), but trigger a panic in
- // debug so we can fix this case.
- if (std.debug.runtime_safety) unreachable else return;
- }
try sema.mod.reference_table.put(sema.gpa, decl_index, .{
.referencer = block.src_decl,
.src = src,
@@ -31945,7 +31789,10 @@ pub fn ensureDeclAnalyzed(sema: *Sema, decl_index: InternPool.DeclIndex) Compile
const ip = &mod.intern_pool;
const decl = mod.declPtr(decl_index);
if (decl.analysis == .in_progress) {
- const msg = try Module.ErrorMsg.create(sema.gpa, decl.srcLoc(mod), "dependency loop detected", .{});
+ const msg = try sema.errMsg(.{
+ .base_node_inst = decl.zir_decl_index.unwrap().?,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ }, "dependency loop detected", .{});
return sema.failWithOwnedErrorMsg(null, msg);
}
@@ -32440,10 +32287,9 @@ fn analyzeSlice(
if (try sema.compareScalar(start_value, .neq, end_value, Type.comptime_int)) {
if (try sema.compareScalar(start_value, .neq, Value.zero_comptime_int, Type.comptime_int)) {
const msg = msg: {
- const msg = try sema.errMsg(block, start_src, bounds_error_message, .{});
+ const msg = try sema.errMsg(start_src, bounds_error_message, .{});
errdefer msg.destroy(sema.gpa);
try sema.errNote(
- block,
start_src,
msg,
"expected '{}', found '{}'",
@@ -32457,10 +32303,9 @@ fn analyzeSlice(
return sema.failWithOwnedErrorMsg(block, msg);
} else if (try sema.compareScalar(end_value, .neq, Value.one_comptime_int, Type.comptime_int)) {
const msg = msg: {
- const msg = try sema.errMsg(block, end_src, bounds_error_message, .{});
+ const msg = try sema.errMsg(end_src, bounds_error_message, .{});
errdefer msg.destroy(sema.gpa);
try sema.errNote(
- block,
end_src,
msg,
"expected '{}', found '{}'",
@@ -32714,9 +32559,9 @@ fn analyzeSlice(
if (!actual_sentinel.eql(expected_sentinel, elem_ty, mod)) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{});
+ const msg = try sema.errMsg(src, "value in memory does not match slice sentinel", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{
+ try sema.errNote(src, msg, "expected '{}', found '{}'", .{
expected_sentinel.fmtValue(mod, sema),
actual_sentinel.fmtValue(mod, sema),
});
@@ -33588,6 +33433,31 @@ const PeerResolveStrategy = enum {
}
};
+const PeerTypeCandidateSrc = union(enum) {
+ /// Do not print out error notes for candidate sources
+ none: void,
+ /// When we want to know the the src of candidate i, look up at
+ /// index i in this slice
+ override: []const ?LazySrcLoc,
+ /// resolvePeerTypes originates from a @TypeOf(...) call
+ typeof_builtin_call_node_offset: i32,
+
+ pub fn resolve(
+ self: PeerTypeCandidateSrc,
+ block: *Block,
+ candidate_i: usize,
+ ) ?LazySrcLoc {
+ return switch (self) {
+ .none => null,
+ .override => |candidate_srcs| if (candidate_i >= candidate_srcs.len)
+ null
+ else
+ candidate_srcs[candidate_i],
+ .typeof_builtin_call_node_offset => |node_offset| block.builtinCallArgSrc(node_offset, @intCast(candidate_i)),
+ };
+ }
+};
+
const PeerResolveResult = union(enum) {
/// The peer type resolution was successful, and resulted in the given type.
success: Type,
@@ -33612,10 +33482,9 @@ const PeerResolveResult = union(enum) {
block: *Block,
src: LazySrcLoc,
instructions: []const Air.Inst.Ref,
- candidate_srcs: Module.PeerTypeCandidateSrc,
+ candidate_srcs: PeerTypeCandidateSrc,
) !*Module.ErrorMsg {
const mod = sema.mod;
- const decl_ptr = mod.declPtr(block.src_decl);
var opt_msg: ?*Module.ErrorMsg = null;
errdefer if (opt_msg) |msg| msg.destroy(sema.gpa);
@@ -33643,9 +33512,9 @@ const PeerResolveResult = union(enum) {
const fmt = "struct field '{}' has conflicting types";
const args = .{field_error.field_name.fmt(&mod.intern_pool)};
if (opt_msg) |msg| {
- try sema.errNote(block, src, msg, fmt, args);
+ try sema.errNote(src, msg, fmt, args);
} else {
- opt_msg = try sema.errMsg(block, src, fmt, args);
+ opt_msg = try sema.errMsg(src, fmt, args);
}
// Continue on to child error
@@ -33667,8 +33536,8 @@ const PeerResolveResult = union(enum) {
peer_tys[conflict_idx[1]],
};
const conflict_srcs: [2]?LazySrcLoc = .{
- candidate_srcs.resolve(mod, decl_ptr, conflict_idx[0]),
- candidate_srcs.resolve(mod, decl_ptr, conflict_idx[1]),
+ candidate_srcs.resolve(block, conflict_idx[0]),
+ candidate_srcs.resolve(block, conflict_idx[1]),
};
const fmt = "incompatible types: '{}' and '{}'";
@@ -33677,16 +33546,16 @@ const PeerResolveResult = union(enum) {
conflict_tys[1].fmt(mod),
};
const msg = if (opt_msg) |msg| msg: {
- try sema.errNote(block, src, msg, fmt, args);
+ try sema.errNote(src, msg, fmt, args);
break :msg msg;
} else msg: {
- const msg = try sema.errMsg(block, src, fmt, args);
+ const msg = try sema.errMsg(src, fmt, args);
opt_msg = msg;
break :msg msg;
};
- if (conflict_srcs[0]) |src_loc| try sema.errNote(block, src_loc, msg, "type '{}' here", .{conflict_tys[0].fmt(mod)});
- if (conflict_srcs[1]) |src_loc| try sema.errNote(block, src_loc, msg, "type '{}' here", .{conflict_tys[1].fmt(mod)});
+ if (conflict_srcs[0]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[0].fmt(mod)});
+ if (conflict_srcs[1]) |src_loc| try sema.errNote(src_loc, msg, "type '{}' here", .{conflict_tys[1].fmt(mod)});
// No child error
break;
@@ -33701,7 +33570,7 @@ fn resolvePeerTypes(
block: *Block,
src: LazySrcLoc,
instructions: []const Air.Inst.Ref,
- candidate_srcs: Module.PeerTypeCandidateSrc,
+ candidate_srcs: PeerTypeCandidateSrc,
) !Type {
switch (instructions.len) {
0 => return Type.noreturn,
@@ -35140,9 +35009,9 @@ pub fn resolveStructAlignment(
}
fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
- const mod = sema.mod;
- const ip = &mod.intern_pool;
- const struct_type = mod.typeToStruct(ty) orelse return;
+ const zcu = sema.mod;
+ const ip = &zcu.intern_pool;
+ const struct_type = zcu.typeToStruct(ty) orelse return;
if (struct_type.haveLayout(ip))
return;
@@ -35150,16 +35019,15 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
try sema.resolveTypeFields(ty);
if (struct_type.layout == .@"packed") {
- try semaBackingIntType(mod, struct_type);
+ try semaBackingIntType(zcu, struct_type);
return;
}
if (struct_type.setLayoutWip(ip)) {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(struct_type.decl.unwrap().?).srcLoc(mod),
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"struct '{}' depends on itself",
- .{ty.fmt(mod)},
+ .{ty.fmt(zcu)},
);
return sema.failWithOwnedErrorMsg(null, msg);
}
@@ -35196,9 +35064,8 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
}
if (struct_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(struct_type.decl.unwrap().?).srcLoc(mod),
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"struct layout depends on it having runtime bits",
.{},
);
@@ -35206,11 +35073,10 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
}
if (struct_type.flagsPtr(ip).assumed_pointer_aligned and
- big_align.compareStrict(.neq, Alignment.fromByteUnits(@divExact(mod.getTarget().ptrBitWidth(), 8))))
+ big_align.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8))))
{
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(struct_type.decl.unwrap().?).srcLoc(mod),
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"struct layout depends on being pointer aligned",
.{},
);
@@ -35242,7 +35108,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
return a_align.compare(.gt, b_align);
}
};
- if (struct_type.isTuple(ip) or !mod.backendSupportsFeature(.field_reordering)) {
+ if (struct_type.isTuple(ip) or !zcu.backendSupportsFeature(.field_reordering)) {
// TODO: don't handle tuples differently. This logic exists only because it
// uncovers latent bugs if removed. Fix the latent bugs and remove this logic!
// Likewise, implement field reordering support in all the backends!
@@ -35293,7 +35159,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co
var analysis_arena = std.heap.ArenaAllocator.init(gpa);
defer analysis_arena.deinit();
- var comptime_err_ret_trace = std.ArrayList(Module.SrcLoc).init(gpa);
+ var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
defer comptime_err_ret_trace.deinit();
var sema: Sema = .{
@@ -35320,6 +35186,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = struct_type.zir_index.unwrap().?,
};
defer assert(block.instructions.items.len == 0);
@@ -35352,7 +35219,10 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co
const backing_int_body_len = zir.extra[extra_index];
extra_index += 1;
- const backing_int_src: LazySrcLoc = .{ .node_offset_container_tag = 0 };
+ const backing_int_src: LazySrcLoc = .{
+ .base_node_inst = struct_type.zir_index.unwrap().?,
+ .offset = .{ .node_offset_container_tag = 0 },
+ };
const backing_int_ty = blk: {
if (backing_int_body_len == 0) {
const backing_int_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
@@ -35368,7 +35238,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co
struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
} else {
if (fields_bit_sum > std.math.maxInt(u16)) {
- return sema.fail(&block, LazySrcLoc.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
+ return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
}
const backing_int_ty = try mod.intType(.unsigned, @intCast(fields_bit_sum));
struct_type.backingIntType(ip).* = backing_int_ty.toIntern();
@@ -35395,9 +35265,9 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
const mod = sema.mod;
if (!ty.isIndexable(mod)) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(src, "type '{}' does not support indexing", .{ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "operand must be an array, slice, tuple, or vector", .{});
+ try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -35418,9 +35288,9 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void
}
}
const msg = msg: {
- const msg = try sema.errMsg(block, src, "type '{}' is not an indexable pointer", .{ty.fmt(sema.mod)});
+ const msg = try sema.errMsg(src, "type '{}' is not an indexable pointer", .{ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{});
+ try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -35471,8 +35341,8 @@ pub fn resolveUnionAlignment(
/// This logic must be kept in sync with `Module.getUnionLayout`.
fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
- const mod = sema.mod;
- const ip = &mod.intern_pool;
+ const zcu = sema.mod;
+ const ip = &zcu.intern_pool;
try sema.resolveTypeFieldsUnion(ty, ip.loadUnionType(ty.ip_index));
@@ -35482,11 +35352,10 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
switch (union_type.flagsPtr(ip).status) {
.none, .have_field_types => {},
.field_types_wip, .layout_wip => {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(union_type.decl).srcLoc(mod),
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"union '{}' depends on itself",
- .{ty.fmt(mod)},
+ .{ty.fmt(zcu)},
);
return sema.failWithOwnedErrorMsg(null, msg);
},
@@ -35505,7 +35374,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
for (0..union_type.field_types.len) |field_index| {
const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);
- if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(mod) == .NoReturn) continue; // TODO: should this affect alignment?
+ if (try sema.typeRequiresComptime(field_ty) or field_ty.zigTypeTag(zcu) == .NoReturn) continue; // TODO: should this affect alignment?
max_size = @max(max_size, sema.typeAbiSize(field_ty) catch |err| switch (err) {
error.AnalysisFail => {
@@ -35547,7 +35416,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
} else {
// {Payload, Tag}
size += max_size;
- size = switch (mod.getTarget().ofmt) {
+ size = switch (zcu.getTarget().ofmt) {
.c => max_align,
else => tag_align,
}.forward(size);
@@ -35566,9 +35435,8 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
flags.status = .have_layout;
if (union_type.flagsPtr(ip).assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(union_type.decl).srcLoc(mod),
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"union layout depends on it having runtime bits",
.{},
);
@@ -35576,11 +35444,10 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
}
if (union_type.flagsPtr(ip).assumed_pointer_aligned and
- alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(mod.getTarget().ptrBitWidth(), 8))))
+ alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8))))
{
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(union_type.decl).srcLoc(mod),
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"union layout depends on being pointer aligned",
.{},
);
@@ -35804,12 +35671,12 @@ pub fn resolveTypeFieldsStruct(
ty: InternPool.Index,
struct_type: InternPool.LoadedStructType,
) CompileError!void {
- const mod = sema.mod;
- const ip = &mod.intern_pool;
+ const zcu = sema.mod;
+ const ip = &zcu.intern_pool;
// If there is no owner decl it means the struct has no fields.
const owner_decl = struct_type.decl.unwrap() orelse return;
- switch (mod.declPtr(owner_decl).analysis) {
+ switch (zcu.declPtr(owner_decl).analysis) {
.file_failure,
.dependency_failure,
.sema_failure,
@@ -35823,20 +35690,19 @@ pub fn resolveTypeFieldsStruct(
if (struct_type.haveFieldTypes(ip)) return;
if (struct_type.setTypesWip(ip)) {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(owner_decl).srcLoc(mod),
+ const msg = try sema.errMsg(
+ Type.fromInterned(ty).srcLoc(zcu),
"struct '{}' depends on itself",
- .{Type.fromInterned(ty).fmt(mod)},
+ .{Type.fromInterned(ty).fmt(zcu)},
);
return sema.failWithOwnedErrorMsg(null, msg);
}
defer struct_type.clearTypesWip(ip);
- semaStructFields(mod, sema.arena, struct_type) catch |err| switch (err) {
+ semaStructFields(zcu, sema.arena, struct_type) catch |err| switch (err) {
error.AnalysisFail => {
- if (mod.declPtr(owner_decl).analysis == .complete) {
- mod.declPtr(owner_decl).analysis = .dependency_failure;
+ if (zcu.declPtr(owner_decl).analysis == .complete) {
+ zcu.declPtr(owner_decl).analysis = .dependency_failure;
}
return error.AnalysisFail;
},
@@ -35845,9 +35711,9 @@ pub fn resolveTypeFieldsStruct(
}
pub fn resolveStructFieldInits(sema: *Sema, ty: Type) CompileError!void {
- const mod = sema.mod;
- const ip = &mod.intern_pool;
- const struct_type = mod.typeToStruct(ty) orelse return;
+ const zcu = sema.mod;
+ const ip = &zcu.intern_pool;
+ const struct_type = zcu.typeToStruct(ty) orelse return;
const owner_decl = struct_type.decl.unwrap() orelse return;
// Inits can start as resolved
@@ -35856,20 +35722,19 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) CompileError!void {
try sema.resolveStructLayout(ty);
if (struct_type.setInitsWip(ip)) {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(owner_decl).srcLoc(mod),
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"struct '{}' depends on itself",
- .{ty.fmt(mod)},
+ .{ty.fmt(zcu)},
);
return sema.failWithOwnedErrorMsg(null, msg);
}
defer struct_type.clearInitsWip(ip);
- semaStructFieldInits(mod, sema.arena, struct_type) catch |err| switch (err) {
+ semaStructFieldInits(zcu, sema.arena, struct_type) catch |err| switch (err) {
error.AnalysisFail => {
- if (mod.declPtr(owner_decl).analysis == .complete) {
- mod.declPtr(owner_decl).analysis = .dependency_failure;
+ if (zcu.declPtr(owner_decl).analysis == .complete) {
+ zcu.declPtr(owner_decl).analysis = .dependency_failure;
}
return error.AnalysisFail;
},
@@ -35879,9 +35744,9 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) CompileError!void {
}
pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) CompileError!void {
- const mod = sema.mod;
- const ip = &mod.intern_pool;
- const owner_decl = mod.declPtr(union_type.decl);
+ const zcu = sema.mod;
+ const ip = &zcu.intern_pool;
+ const owner_decl = zcu.declPtr(union_type.decl);
switch (owner_decl.analysis) {
.file_failure,
.dependency_failure,
@@ -35895,11 +35760,10 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
switch (union_type.flagsPtr(ip).status) {
.none => {},
.field_types_wip => {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- owner_decl.srcLoc(mod),
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"union '{}' depends on itself",
- .{ty.fmt(mod)},
+ .{ty.fmt(zcu)},
);
return sema.failWithOwnedErrorMsg(null, msg);
},
@@ -35913,7 +35777,7 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
union_type.flagsPtr(ip).status = .field_types_wip;
errdefer union_type.flagsPtr(ip).status = .none;
- semaUnionFields(mod, sema.arena, union_type) catch |err| switch (err) {
+ semaUnionFields(zcu, sema.arena, union_type) catch |err| switch (err) {
error.AnalysisFail => {
if (owner_decl.analysis == .complete) {
owner_decl.analysis = .dependency_failure;
@@ -35963,10 +35827,13 @@ fn resolveInferredErrorSet(
} else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) {
if (ies_func_info.is_generic) {
const msg = msg: {
- const msg = try sema.errMsg(block, src, "unable to resolve inferred error set of generic function", .{});
+ const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{});
errdefer msg.destroy(sema.gpa);
- try sema.mod.errNoteNonLazy(ies_func_owner_decl.srcLoc(mod), msg, "generic function declared here", .{});
+ try sema.errNote(.{
+ .base_node_inst = ies_func_owner_decl.zir_decl_index.unwrap().?,
+ .offset = LazySrcLoc.Offset.nodeOffset(0),
+ }, msg, "generic function declared here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
@@ -36147,7 +36014,7 @@ fn semaStructFields(
},
};
- var comptime_err_ret_trace = std.ArrayList(Module.SrcLoc).init(gpa);
+ var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
defer comptime_err_ret_trace.deinit();
var sema: Sema = .{
@@ -36174,6 +36041,7 @@ fn semaStructFields(
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = struct_type.zir_index.unwrap().?,
};
defer assert(block_scope.instructions.items.len == 0);
@@ -36252,35 +36120,19 @@ fn semaStructFields(
// so that init values may depend on type layout.
for (fields, 0..) |zir_field, field_i| {
+ const ty_src: LazySrcLoc = .{
+ .base_node_inst = struct_type.zir_index.unwrap().?,
+ .offset = .{ .container_field_type = @intCast(field_i) },
+ };
const field_ty: Type = ty: {
if (zir_field.type_ref != .none) {
- break :ty sema.resolveType(&block_scope, .unneeded, zir_field.type_ref) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const ty_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .type,
- }).lazy;
- _ = try sema.resolveType(&block_scope, ty_src, zir_field.type_ref);
- unreachable;
- },
- else => |e| return e,
- };
+ break :ty try sema.resolveType(&block_scope, ty_src, zir_field.type_ref);
}
assert(zir_field.type_body_len != 0);
const body = zir.bodySlice(extra_index, zir_field.type_body_len);
extra_index += body.len;
const ty_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
- break :ty sema.analyzeAsType(&block_scope, .unneeded, ty_ref) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const ty_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .type,
- }).lazy;
- _ = try sema.analyzeAsType(&block_scope, ty_src, ty_ref);
- unreachable;
- },
- else => |e| return e,
- };
+ break :ty try sema.analyzeAsType(&block_scope, ty_src, ty_ref);
};
if (field_ty.isGenericPoison()) {
return error.GenericPoison;
@@ -36290,11 +36142,7 @@ fn semaStructFields(
if (field_ty.zigTypeTag(mod) == .Opaque) {
const msg = msg: {
- const ty_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .type,
- }).lazy;
- const msg = try sema.errMsg(&block_scope, ty_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
+ const msg = try sema.errMsg(ty_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, field_ty);
@@ -36304,11 +36152,7 @@ fn semaStructFields(
}
if (field_ty.zigTypeTag(mod) == .NoReturn) {
const msg = msg: {
- const ty_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .type,
- }).lazy;
- const msg = try sema.errMsg(&block_scope, ty_src, "struct fields cannot be 'noreturn'", .{});
+ const msg = try sema.errMsg(ty_src, "struct fields cannot be 'noreturn'", .{});
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, field_ty);
@@ -36319,11 +36163,7 @@ fn semaStructFields(
switch (struct_type.layout) {
.@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {
const msg = msg: {
- const ty_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .type,
- });
- const msg = try sema.errMsg(&block_scope, ty_src.lazy, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
+ const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field);
@@ -36335,11 +36175,7 @@ fn semaStructFields(
},
.@"packed" => if (!try sema.validatePackedType(field_ty)) {
const msg = msg: {
- const ty_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .type,
- });
- const msg = try sema.errMsg(&block_scope, ty_src.lazy, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
+ const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty);
@@ -36356,17 +36192,11 @@ fn semaStructFields(
const body = zir.bodySlice(extra_index, zir_field.align_body_len);
extra_index += body.len;
const align_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
- const field_align = sema.analyzeAsAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const align_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .alignment,
- }).lazy;
- _ = try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
- unreachable;
- },
- else => |e| return e,
+ const align_src: LazySrcLoc = .{
+ .base_node_inst = struct_type.zir_index.unwrap().?,
+ .offset = .{ .container_field_align = @intCast(field_i) },
};
+ const field_align = try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
struct_type.field_aligns.get(ip)[field_i] = field_align;
}
@@ -36395,7 +36225,7 @@ fn semaStructFieldInits(
const zir_index = struct_type.zir_index.unwrap().?.resolve(ip);
const fields_len, const small, var extra_index = structZirInfo(zir, zir_index);
- var comptime_err_ret_trace = std.ArrayList(Module.SrcLoc).init(gpa);
+ var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
defer comptime_err_ret_trace.deinit();
var sema: Sema = .{
@@ -36422,6 +36252,7 @@ fn semaStructFieldInits(
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = struct_type.zir_index.unwrap().?,
};
defer assert(block_scope.instructions.items.len == 0);
@@ -36495,33 +36326,20 @@ fn semaStructFieldInits(
try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index});
sema.inst_map.putAssumeCapacity(zir_index, type_ref);
- const init = try sema.resolveInlineBody(&block_scope, body, zir_index);
- const coerced = sema.coerce(&block_scope, field_ty, init, .unneeded) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const init_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .value,
- }).lazy;
- _ = try sema.coerce(&block_scope, field_ty, init, init_src);
- unreachable;
- },
- else => |e| return e,
+ const init_src: LazySrcLoc = .{
+ .base_node_inst = struct_type.zir_index.unwrap().?,
+ .offset = .{ .container_field_value = @intCast(field_i) },
};
- const default_val = (try sema.resolveValue(coerced)) orelse {
- const init_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .value,
- }).lazy;
+
+ const init = try sema.resolveInlineBody(&block_scope, body, zir_index);
+ const coerced = try sema.coerce(&block_scope, field_ty, init, init_src);
+ const default_val = try sema.resolveValue(coerced) orelse {
return sema.failWithNeededComptime(&block_scope, init_src, .{
.needed_comptime_reason = "struct field default value must be comptime-known",
});
};
if (default_val.canMutateComptimeVarState(mod)) {
- const init_src = mod.fieldSrcLoc(decl_index, .{
- .index = field_i,
- .range = .value,
- }).lazy;
return sema.fail(&block_scope, init_src, "field default value contains reference to comptime-mutable memory", .{});
}
struct_type.field_inits.get(ip)[field_i] = default_val.toIntern();
@@ -36543,8 +36361,6 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.UnionDecl).Struct.fields.len;
- const src = LazySrcLoc.nodeOffset(0);
-
const tag_type_ref: Zir.Inst.Ref = if (small.has_tag_type) blk: {
const ty_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
extra_index += 1;
@@ -36583,7 +36399,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
const decl = mod.declPtr(decl_index);
- var comptime_err_ret_trace = std.ArrayList(Module.SrcLoc).init(gpa);
+ var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa);
defer comptime_err_ret_trace.deinit();
var sema: Sema = .{
@@ -36610,9 +36426,12 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = union_type.zir_index,
};
defer assert(block_scope.instructions.items.len == 0);
+ const src = block_scope.nodeOffset(0);
+
if (body.len != 0) {
_ = try sema.analyzeInlineBody(&block_scope, body, zir_index);
}
@@ -36622,7 +36441,10 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
var enum_field_vals: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{};
var explicit_tags_seen: []bool = &.{};
if (tag_type_ref != .none) {
- const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x };
+ const tag_ty_src: LazySrcLoc = .{
+ .base_node_inst = union_type.zir_index,
+ .offset = .{ .node_offset_container_tag = 0 },
+ };
const provided_ty = try sema.resolveType(&block_scope, tag_ty_src, tag_type_ref);
if (small.auto_enum_tag) {
// The provided type is an integer type and we must construct the enum tag type here.
@@ -36635,9 +36457,9 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
const field_count_val = try mod.intValue(Type.comptime_int, fields_len - 1);
if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) {
const msg = msg: {
- const msg = try sema.errMsg(&block_scope, tag_ty_src, "specified integer tag type cannot represent every field", .{});
+ const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(&block_scope, tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{
+ try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{
int_tag_ty.fmt(mod),
fields_len - 1,
});
@@ -36722,19 +36544,26 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
break :blk try sema.resolveInst(tag_ref);
} else .none;
+ const name_src: LazySrcLoc = .{
+ .base_node_inst = union_type.zir_index,
+ .offset = .{ .container_field_name = field_i },
+ };
+ const value_src: LazySrcLoc = .{
+ .base_node_inst = union_type.zir_index,
+ .offset = .{ .container_field_value = field_i },
+ };
+ const align_src: LazySrcLoc = .{
+ .base_node_inst = union_type.zir_index,
+ .offset = .{ .container_field_align = field_i },
+ };
+ const type_src: LazySrcLoc = .{
+ .base_node_inst = union_type.zir_index,
+ .offset = .{ .container_field_type = field_i },
+ };
+
if (enum_field_vals.capacity() > 0) {
const enum_tag_val = if (tag_ref != .none) blk: {
- const val = sema.semaUnionFieldVal(&block_scope, .unneeded, int_tag_ty, tag_ref) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const val_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .value,
- }).lazy;
- _ = try sema.semaUnionFieldVal(&block_scope, val_src, int_tag_ty, tag_ref);
- unreachable;
- },
- else => |e| return e,
- };
+ const val = try sema.semaUnionFieldVal(&block_scope, value_src, int_tag_ty, tag_ref);
last_tag_val = val;
break :blk val;
@@ -36749,12 +36578,14 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
};
const gop = enum_field_vals.getOrPutAssumeCapacity(enum_tag_val.toIntern());
if (gop.found_existing) {
- const field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = field_i }).lazy;
- const other_field_src = mod.fieldSrcLoc(union_type.decl, .{ .index = gop.index }).lazy;
+ const other_value_src: LazySrcLoc = .{
+ .base_node_inst = union_type.zir_index,
+ .offset = .{ .container_field_value = @intCast(gop.index) },
+ };
const msg = msg: {
- const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(mod, &sema)});
+ const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(mod, &sema)});
errdefer msg.destroy(gpa);
- try sema.errNote(&block_scope, other_field_src, msg, "other occurrence here", .{});
+ try sema.errNote(other_value_src, msg, "other occurrence here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(&block_scope, msg);
@@ -36772,17 +36603,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
else if (field_type_ref == .none)
Type.noreturn
else
- sema.resolveType(&block_scope, .unneeded, field_type_ref) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const ty_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .type,
- }).lazy;
- _ = try sema.resolveType(&block_scope, ty_src, field_type_ref);
- unreachable;
- },
- else => |e| return e,
- };
+ try sema.resolveType(&block_scope, type_src, field_type_ref);
if (field_ty.isGenericPoison()) {
return error.GenericPoison;
@@ -36791,11 +36612,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
if (explicit_tags_seen.len > 0) {
const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);
const enum_index = tag_info.nameIndex(ip, field_name) orelse {
- const ty_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .name,
- }).lazy;
- return sema.fail(&block_scope, ty_src, "no field named '{}' in enum '{}'", .{
+ return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{
field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(mod),
});
};
@@ -36808,17 +36625,15 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
// Enforce the enum fields and the union fields being in the same order.
if (enum_index != field_i) {
const msg = msg: {
- const ty_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .name,
- }).lazy;
- const enum_field_src = mod.fieldSrcLoc(tag_info.decl, .{ .index = enum_index }).lazy;
- const msg = try sema.errMsg(&block_scope, ty_src, "union field '{}' ordered differently than corresponding enum field", .{
+ const enum_field_src: LazySrcLoc = .{
+ .base_node_inst = tag_info.zir_index.unwrap().?,
+ .offset = .{ .container_field_name = enum_index },
+ };
+ const msg = try sema.errMsg(name_src, "union field '{}' ordered differently than corresponding enum field", .{
field_name.fmt(ip),
});
errdefer msg.destroy(sema.gpa);
- const decl_ptr = mod.declPtr(tag_info.decl);
- try mod.errNoteNonLazy(decl_ptr.toSrcLoc(enum_field_src, mod), msg, "enum field here", .{});
+ try sema.errNote(enum_field_src, msg, "enum field here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(&block_scope, msg);
@@ -36827,11 +36642,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
if (field_ty.zigTypeTag(mod) == .Opaque) {
const msg = msg: {
- const ty_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .type,
- }).lazy;
- const msg = try sema.errMsg(&block_scope, ty_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
+ const msg = try sema.errMsg(type_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, field_ty);
@@ -36844,14 +36655,10 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
!try sema.validateExternType(field_ty, .union_field))
{
const msg = msg: {
- const ty_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .type,
- });
- const msg = try sema.errMsg(&block_scope, ty_src.lazy, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
+ const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .union_field);
+ try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field);
try sema.addDeclaredHereNote(msg, field_ty);
break :msg msg;
@@ -36859,14 +36666,10 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
return sema.failWithOwnedErrorMsg(&block_scope, msg);
} else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
const msg = msg: {
- const ty_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .type,
- });
- const msg = try sema.errMsg(&block_scope, ty_src.lazy, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
+ const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)});
errdefer msg.destroy(sema.gpa);
- try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty);
+ try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty);
try sema.addDeclaredHereNote(msg, field_ty);
break :msg msg;
@@ -36878,17 +36681,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
if (small.any_aligned_fields) {
field_aligns.appendAssumeCapacity(if (align_ref != .none)
- sema.resolveAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) {
- error.NeededSourceLocation => {
- const align_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .alignment,
- }).lazy;
- _ = try sema.resolveAlign(&block_scope, align_src, align_ref);
- unreachable;
- },
- else => |e| return e,
- }
+ try sema.resolveAlign(&block_scope, align_src, align_ref)
else
.none);
} else {
@@ -36903,7 +36696,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded
const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*);
if (tag_info.names.len > fields_len) {
const msg = msg: {
- const msg = try sema.errMsg(&block_scope, src, "enum field(s) missing in union", .{});
+ const msg = try sema.errMsg(src, "enum field(s) missing in union", .{});
errdefer msg.destroy(sema.gpa);
for (tag_info.names.get(ip), 0..) |field_name, field_index| {
@@ -36945,7 +36738,7 @@ fn generateUnionTagTypeNumbered(
const ip = &mod.intern_pool;
const src_decl = mod.declPtr(block.src_decl);
- const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node);
+ const new_decl_index = try mod.allocateNewDecl(block.namespace);
errdefer mod.destroyDecl(new_decl_index);
const fqn = try union_owner_decl.fullyQualifiedName(mod);
const name = try ip.getOrPutStringFmt(
@@ -36997,7 +36790,7 @@ fn generateUnionTagTypeSimple(
const new_decl_index = new_decl_index: {
const fqn = try union_owner_decl.fullyQualifiedName(mod);
const src_decl = mod.declPtr(block.src_decl);
- const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node);
+ const new_decl_index = try mod.allocateNewDecl(block.namespace);
errdefer mod.destroyDecl(new_decl_index);
const name = try ip.getOrPutStringFmt(
gpa,
@@ -37037,8 +36830,7 @@ fn generateUnionTagTypeSimple(
}
fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
- const gpa = sema.gpa;
- const src = LazySrcLoc.nodeOffset(0);
+ const zcu = sema.mod;
var block: Block = .{
.parent = null,
@@ -37048,8 +36840,23 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = sema.owner_decl.zir_decl_index.unwrap() orelse owner: {
+ assert(sema.owner_decl.has_tv);
+ assert(sema.owner_decl.owns_tv);
+ switch (sema.owner_decl.typeOf(zcu).zigTypeTag(zcu)) {
+ .Type => break :owner sema.owner_decl.val.toType().typeDeclInst(zcu).?,
+ .Fn => {
+ const owner = zcu.funcInfo(sema.owner_decl.val.toIntern()).generic_owner;
+ const generic_owner_decl = zcu.declPtr(zcu.funcInfo(owner).owner_decl);
+ break :owner generic_owner_decl.zir_decl_index.unwrap().?;
+ },
+ else => unreachable,
+ }
+ },
};
- defer block.instructions.deinit(gpa);
+ defer block.instructions.deinit(sema.gpa);
+
+ const src = block.nodeOffset(0);
const decl_index = try getBuiltinDecl(sema, &block, name);
return sema.analyzeDeclVal(&block, src, decl_index);
@@ -37058,7 +36865,7 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
fn getBuiltinDecl(sema: *Sema, block: *Block, name: []const u8) CompileError!InternPool.DeclIndex {
const gpa = sema.gpa;
- const src = LazySrcLoc.nodeOffset(0);
+ const src = block.nodeOffset(0);
const mod = sema.mod;
const ip = &mod.intern_pool;
@@ -37085,6 +36892,7 @@ fn getBuiltinDecl(sema: *Sema, block: *Block, name: []const u8) CompileError!Int
}
fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
+ const zcu = sema.mod;
const ty_inst = try sema.getBuiltin(name);
var block: Block = .{
@@ -37095,9 +36903,23 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
.instructions = .{},
.inlining = null,
.is_comptime = true,
+ .src_base_inst = sema.owner_decl.zir_decl_index.unwrap() orelse owner: {
+ assert(sema.owner_decl.has_tv);
+ assert(sema.owner_decl.owns_tv);
+ switch (sema.owner_decl.typeOf(zcu).zigTypeTag(zcu)) {
+ .Type => break :owner sema.owner_decl.val.toType().typeDeclInst(zcu).?,
+ .Fn => {
+ const owner = zcu.funcInfo(sema.owner_decl.val.toIntern()).generic_owner;
+ const generic_owner_decl = zcu.declPtr(zcu.funcInfo(owner).owner_decl);
+ break :owner generic_owner_decl.zir_decl_index.unwrap().?;
+ },
+ else => unreachable,
+ }
+ },
};
defer block.instructions.deinit(sema.gpa);
- const src = LazySrcLoc.nodeOffset(0);
+
+ const src = block.nodeOffset(0);
const result_ty = sema.analyzeAsType(&block, src, ty_inst) catch |err| switch (err) {
error.AnalysisFail => std.debug.panic("std.builtin.{s} is corrupt", .{name}),
@@ -37113,12 +36935,12 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
/// that the types are already resolved.
/// TODO assert the return value matches `ty.onePossibleValue`
pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
- const mod = sema.mod;
- const ip = &mod.intern_pool;
+ const zcu = sema.mod;
+ const ip = &zcu.intern_pool;
return switch (ty.toIntern()) {
.u0_type,
.i0_type,
- => try mod.intValue(ty, 0),
+ => try zcu.intValue(ty, 0),
.u1_type,
.u8_type,
.i8_type,
@@ -37181,7 +37003,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
.anyframe_type => unreachable,
.null_type => Value.null,
.undefined_type => Value.undef,
- .optional_noreturn_type => try mod.nullValue(ty),
+ .optional_noreturn_type => try zcu.nullValue(ty),
.generic_poison_type => error.GenericPoison,
.empty_struct_type => Value.empty_struct,
// values, not types
@@ -37295,13 +37117,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
=> switch (ip.indexToKey(ty.toIntern())) {
inline .array_type, .vector_type => |seq_type, seq_tag| {
const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
- if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned((try mod.intern(.{ .aggregate = .{
+ if (seq_type.len + @intFromBool(has_sentinel) == 0) return Value.fromInterned((try zcu.intern(.{ .aggregate = .{
.ty = ty.toIntern(),
.storage = .{ .elems = &.{} },
} })));
if (try sema.typeHasOnePossibleValue(Type.fromInterned(seq_type.child))) |opv| {
- return Value.fromInterned((try mod.intern(.{ .aggregate = .{
+ return Value.fromInterned((try zcu.intern(.{ .aggregate = .{
.ty = ty.toIntern(),
.storage = .{ .repeated_elem = opv.toIntern() },
} })));
@@ -37316,7 +37138,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
if (struct_type.field_types.len == 0) {
// In this case the struct has no fields at all and
// therefore has one possible value.
- return Value.fromInterned((try mod.intern(.{ .aggregate = .{
+ return Value.fromInterned((try zcu.intern(.{ .aggregate = .{
.ty = ty.toIntern(),
.storage = .{ .elems = &.{} },
} })));
@@ -37333,12 +37155,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
continue;
}
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
- if (field_ty.eql(ty, mod)) {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(struct_type.decl.unwrap().?).srcLoc(mod),
+ if (field_ty.eql(ty, zcu)) {
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"struct '{}' depends on itself",
- .{ty.fmt(mod)},
+ .{ty.fmt(zcu)},
);
try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
return sema.failWithOwnedErrorMsg(null, msg);
@@ -37350,7 +37171,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
// In this case the struct has no runtime-known fields and
// therefore has one possible value.
- return Value.fromInterned((try mod.intern(.{ .aggregate = .{
+ return Value.fromInterned((try zcu.intern(.{ .aggregate = .{
.ty = ty.toIntern(),
.storage = .{ .elems = field_vals },
} })));
@@ -37363,7 +37184,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
// In this case the struct has all comptime-known fields and
// therefore has one possible value.
// TODO: write something like getCoercedInts to avoid needing to dupe
- return Value.fromInterned((try mod.intern(.{ .aggregate = .{
+ return Value.fromInterned((try zcu.intern(.{ .aggregate = .{
.ty = ty.toIntern(),
.storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) },
} })));
@@ -37375,23 +37196,22 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse
return null;
if (union_obj.field_types.len == 0) {
- const only = try mod.intern(.{ .empty_enum_value = ty.toIntern() });
+ const only = try zcu.intern(.{ .empty_enum_value = ty.toIntern() });
return Value.fromInterned(only);
}
const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);
- if (only_field_ty.eql(ty, mod)) {
- const msg = try Module.ErrorMsg.create(
- sema.gpa,
- mod.declPtr(union_obj.decl).srcLoc(mod),
+ if (only_field_ty.eql(ty, zcu)) {
+ const msg = try sema.errMsg(
+ ty.srcLoc(zcu),
"union '{}' depends on itself",
- .{ty.fmt(mod)},
+ .{ty.fmt(zcu)},
);
try sema.addFieldErrNote(ty, 0, msg, "while checking this field", .{});
return sema.failWithOwnedErrorMsg(null, msg);
}
const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse
return null;
- const only = try mod.intern(.{ .un = .{
+ const only = try zcu.intern(.{ .un = .{
.ty = ty.toIntern(),
.tag = tag_val.toIntern(),
.val = val_val.toIntern(),
@@ -37406,7 +37226,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
if (enum_type.tag_ty == .comptime_int_type) return null;
if (try sema.typeHasOnePossibleValue(Type.fromInterned(enum_type.tag_ty))) |int_opv| {
- const only = try mod.intern(.{ .enum_tag = .{
+ const only = try zcu.intern(.{ .enum_tag = .{
.ty = ty.toIntern(),
.int = int_opv.toIntern(),
} });
@@ -37416,18 +37236,18 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
return null;
},
.auto, .explicit => {
- if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(mod)) return null;
+ if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null;
return Value.fromInterned(switch (enum_type.names.len) {
- 0 => try mod.intern(.{ .empty_enum_value = ty.toIntern() }),
- 1 => try mod.intern(.{ .enum_tag = .{
+ 0 => try zcu.intern(.{ .empty_enum_value = ty.toIntern() }),
+ 1 => try zcu.intern(.{ .enum_tag = .{
.ty = ty.toIntern(),
.int = if (enum_type.values.len == 0)
- (try mod.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern()
+ (try zcu.intValue(Type.fromInterned(enum_type.tag_ty), 0)).toIntern()
else
- try mod.intern_pool.getCoercedInts(
- mod.gpa,
- mod.intern_pool.indexToKey(enum_type.values.get(ip)[0]).int,
+ try zcu.intern_pool.getCoercedInts(
+ zcu.gpa,
+ zcu.intern_pool.indexToKey(enum_type.values.get(ip)[0]).int,
enum_type.tag_ty,
),
} }),
@@ -37765,7 +37585,7 @@ fn unionFieldIndex(
try sema.resolveTypeFields(union_ty);
const union_obj = mod.typeToUnion(union_ty).?;
const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse
- return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
+ return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);
return @intCast(field_index);
}
@@ -37784,7 +37604,7 @@ fn structFieldIndex(
} else {
const struct_type = mod.typeToStruct(struct_ty).?;
return struct_type.nameIndex(ip, field_name) orelse
- return sema.failWithBadStructFieldAccess(block, struct_type, field_src, field_name);
+ return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_src, field_name);
}
}
@@ -38556,9 +38376,9 @@ fn checkRuntimeValue(sema: *Sema, ptr: Air.Inst.Ref) bool {
fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Air.Inst.Ref) CompileError!void {
if (sema.checkRuntimeValue(val)) return;
return sema.failWithOwnedErrorMsg(block, msg: {
- const msg = try sema.errMsg(block, val_src, "runtime value contains reference to comptime var", .{});
+ const msg = try sema.errMsg(val_src, "runtime value contains reference to comptime var", .{});
errdefer msg.destroy(sema.gpa);
- try sema.errNote(block, val_src, msg, "comptime var pointers are not available at runtime", .{});
+ try sema.errNote(val_src, msg, "comptime var pointers are not available at runtime", .{});
break :msg msg;
});
}
@@ -38649,6 +38469,14 @@ fn maybeDerefSliceAsArray(
return sema.pointerDeref(block, src, casted_ptr, ptr_ty);
}
+fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check: bool) !void {
+ if (safety_check and block.wantSafety()) {
+ try sema.safetyPanic(block, src, .unreach);
+ } else {
+ _ = try block.addNoOp(.unreach);
+ }
+}
+
pub const bitCastVal = @import("Sema/bitcast.zig").bitCast;
pub const bitCastSpliceVal = @import("Sema/bitcast.zig").bitCastSplice;
src/type.zig
@@ -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;
}
src/Value.zig
@@ -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,
test/cases/compile_errors/comptime_arg_to_generic_fn_callee_error.zig
@@ -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
test/cases/compile_errors/enum_value_already_taken.zig
@@ -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
test/cases/compile_errors/export_function_with_comptime_parameter.zig
@@ -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'
test/cases/compile_errors/export_generic_function.zig
@@ -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'
test/cases/compile_errors/extern_function_with_comptime_parameter.zig
@@ -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'
test/cases/compile_errors/missing_field_in_struct_value_expression.zig
@@ -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
test/cases/compile_errors/missing_struct_field_in_fn_called_at_comptime.zig
@@ -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
test/cases/compile_errors/reify_type_for_tagged_union_with_extra_enum_field.zig
@@ -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
test/cases/compile_errors/reify_type_for_tagged_union_with_extra_union_field.zig
@@ -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
test/cases/compile_errors/reify_type_for_tagged_union_with_no_enum_fields.zig
@@ -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
test/cases/compile_errors/reify_type_for_tagged_union_with_no_union_fields.zig
@@ -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
test/cases/compile_errors/switch_ranges_endpoints_are_validated.zig
@@ -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
test/cases/compile_errors/union_auto-enum_value_already_taken.zig
@@ -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