diff options
| author | Matthew Lugg <mlugg@mlugg.co.uk> | 2024-06-20 11:07:17 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-20 11:07:17 +0100 |
| commit | f73be120f4254c080c48081dfc5834a7ebc9d9cf (patch) | |
| tree | e70598bed09659eb61c230620c1ddf88c14db905 /src/Sema.zig | |
| parent | ccd3cc3266762c1fea93cdc0190eaf71718d9e6a (diff) | |
| parent | 2b677d1660018434757f9c9efec3c712675e6c47 (diff) | |
| download | zig-f73be120f4254c080c48081dfc5834a7ebc9d9cf.tar.gz zig-f73be120f4254c080c48081dfc5834a7ebc9d9cf.zip | |
Merge pull request #20299 from mlugg/the-great-decl-split
The Great Decl Split (preliminary work): refactor source locations and eliminate `Sema.Block.src_decl`.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 3695 |
1 files changed, 1789 insertions, 1906 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index df783a118c..26696328f7 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -16,9 +16,7 @@ air_instructions: std.MultiArrayList(Air.Inst) = .{}, air_extra: std.ArrayListUnmanaged(u32) = .{}, /// Maps ZIR to AIR. inst_map: InstMap = .{}, -/// When analyzing an inline function call, owner_decl is the Decl of the caller -/// and `src_decl` of `Block` is the `Decl` of the callee. -/// This `Decl` owns the arena memory of this `Sema`. +/// When analyzing an inline function call, owner_decl is the Decl of the caller. owner_decl: *Decl, owner_decl_index: InternPool.DeclIndex, /// For an inline or comptime function call, this will be the root parent function @@ -34,7 +32,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 +63,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 +127,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, }) = .{}, }; @@ -182,7 +177,7 @@ const Namespace = Module.Namespace; const CompileError = Module.CompileError; const SemaError = Module.SemaError; const Decl = Module.Decl; -const LazySrcLoc = std.zig.LazySrcLoc; +const LazySrcLoc = Zcu.LazySrcLoc; const RangeSet = @import("RangeSet.zig"); const target_util = @import("target.zig"); const Package = @import("Package.zig"); @@ -345,7 +340,6 @@ pub const Block = struct { /// Shared among all child blocks. sema: *Sema, /// The namespace to use for lookups from this source block - /// When analyzing fields, this is different from src_decl.src_namespace. namespace: InternPool.NamespaceIndex, /// The AIR instructions generated for this block. instructions: std.ArrayListUnmanaged(Air.Inst.Index), @@ -361,12 +355,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, - /// 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. - src_decl: InternPool.DeclIndex, + runtime_cond: ?LazySrcLoc = null, + runtime_loop: ?LazySrcLoc = null, /// Non zero if a non-inline loop or a runtime conditional have been encountered. /// Stores to comptime variables are only allowed when var.runtime_index <= runtime_index. runtime_index: Value.RuntimeIndex = .zero, @@ -395,13 +385,45 @@ pub const Block = struct { /// `block` in order for codegen to match lexical scoping for debug vars. need_debug_scope: ?*bool = null, + /// 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, + + /// The name of the current "context" for naming namespace types. + /// The interpretation of this depends on the name strategy in ZIR, but the name + /// is always incorporated into the type name somehow. + /// See `Sema.createAnonymousDeclTypeNamed`. + type_name_ctx: InternPool.NullTerminatedString, + + /// 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 { + return block.src(LazySrcLoc.Offset.nodeOffset(node_offset)); + } + + fn tokenOffset(block: Block, tok_offset: u32) LazySrcLoc { + 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, @@ -413,27 +435,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); }, } } @@ -497,7 +515,6 @@ pub const Block = struct { return .{ .parent = parent, .sema = parent.sema, - .src_decl = parent.src_decl, .namespace = parent.namespace, .instructions = .{}, .label = null, @@ -513,6 +530,8 @@ 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, + .type_name_ctx = parent.type_name_ctx, }; } @@ -803,14 +822,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; @@ -981,9 +992,16 @@ fn analyzeBodyInner( while (true) { crash_info.setBodyIndex(i); const inst = body[i]; - std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ - mod.namespacePtr(mod.declPtr(block.src_decl).src_namespace).file_scope.sub_file_path, inst, - }); + + // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away. + if (build_options.enable_logging) { + std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ sub_file_path: { + const path_digest = block.src_base_inst.resolveFull(&mod.intern_pool).path_digest; + const index = mod.path_digest_map.getIndex(path_digest).?; + break :sub_file_path mod.import_table.values()[index].sub_file_path; + }, inst }); + } + const air_inst: Air.Inst.Ref = switch (tags[@intFromEnum(inst)]) { // zig fmt: off .alloc => try sema.zirAlloc(block, inst), @@ -1225,7 +1243,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), @@ -1449,7 +1467,7 @@ fn analyzeBodyInner( .check_comptime_control_flow => { if (!block.is_comptime) { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const inline_block = inst_data.operand.toIndex().?; var check_block = block; @@ -1463,10 +1481,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); @@ -1482,13 +1499,13 @@ fn analyzeBodyInner( }, .restore_err_ret_index_unconditional => { const un_node = datas[@intFromEnum(inst)].un_node; - try sema.restoreErrRetIndex(block, un_node.src(), un_node.operand, .none); + try sema.restoreErrRetIndex(block, block.nodeOffset(un_node.src_node), un_node.operand, .none); i += 1; continue; }, .restore_err_ret_index_fn_entry => { const un_node = datas[@intFromEnum(inst)].un_node; - try sema.restoreErrRetIndex(block, un_node.src(), .none, un_node.operand); + try sema.restoreErrRetIndex(block, block.nodeOffset(un_node.src_node), .none, un_node.operand); i += 1; continue; }, @@ -1510,7 +1527,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; @@ -1523,7 +1540,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; @@ -1667,7 +1684,7 @@ fn analyzeBodyInner( try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]); block.instructions.items.len = block_index; - const block_result = try sema.resolveAnalyzedBlock(block, inst_data.src(), &labeled_block.block, &labeled_block.label.merges, need_debug_scope); + const block_result = try sema.resolveAnalyzedBlock(block, block.nodeOffset(inst_data.src_node), &labeled_block.block, &labeled_block.label.merges, need_debug_scope); { // Destroy the ad-hoc block entry so that it does not interfere with // the next iteration of comptime control flow, if any. @@ -1693,7 +1710,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( @@ -1713,7 +1730,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( @@ -1736,8 +1753,8 @@ fn analyzeBodyInner( .@"try" => blk: { 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -1762,8 +1779,8 @@ fn analyzeBodyInner( .try_ptr => blk: { 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -1927,14 +1944,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(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", .{}), + switch (sema.genericPoisonReason(block, zir_ref)) { + .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); @@ -1963,7 +1980,7 @@ const GenericPoisonReason = union(enum) { /// Backtracks through ZIR instructions to determine the reason a generic poison /// type was created. Used for error reporting. -fn genericPoisonReason(sema: *Sema, ref: Zir.Inst.Ref) GenericPoisonReason { +fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoisonReason { var cur = ref; while (true) { const inst = cur.toIndex() orelse return .unknown; @@ -1999,7 +2016,7 @@ fn genericPoisonReason(sema: *Sema, ref: Zir.Inst.Ref) GenericPoisonReason { cur = un_node.operand; } else { // This must be an anyopaque pointer! - return .{ .anyopaque_ptr = un_node.src() }; + return .{ .anyopaque_ptr = block.nodeOffset(un_node.src_node) }; } }, .call, .field_call => { @@ -2007,7 +2024,7 @@ fn genericPoisonReason(sema: *Sema, ref: Zir.Inst.Ref) GenericPoisonReason { // evaluating an `anytype` function parameter. // TODO: better source location - function decl rather than call const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - return .{ .anytype_param = pl_node.src() }; + return .{ .anytype_param = block.nodeOffset(pl_node.src_node) }; }, else => return .unknown, } @@ -2039,7 +2056,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; @@ -2200,9 +2217,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); @@ -2229,12 +2246,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; @@ -2245,12 +2262,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; }; @@ -2279,11 +2296,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); @@ -2296,15 +2313,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); @@ -2312,7 +2328,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; }; @@ -2333,9 +2349,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); @@ -2343,9 +2359,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); @@ -2378,11 +2394,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; }; @@ -2391,17 +2407,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( @@ -2413,52 +2427,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( @@ -2468,7 +2453,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); @@ -2502,7 +2487,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", @@ -2536,7 +2520,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; @@ -2571,15 +2555,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; @@ -2716,7 +2698,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: { @@ -2725,7 +2707,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 }); }, }; @@ -2776,7 +2758,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 = extra.data.src(); + + 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: { @@ -2820,7 +2808,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, } }, }; @@ -2835,11 +2823,11 @@ fn zirStructDecl( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, Value.fromInterned(wip_ty.index), small.name_strategy, "struct", inst, + extra.data.src_line, ); mod.declPtr(new_decl_index).owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -2872,42 +2860,26 @@ fn zirStructDecl( fn createAnonymousDeclTypeNamed( sema: *Sema, block: *Block, - src: LazySrcLoc, val: Value, name_strategy: Zir.Inst.NameStrategy, anon_prefix: []const u8, inst: ?Zir.Inst.Index, + src_line: u32, ) !InternPool.DeclIndex { const zcu = sema.mod; const ip = &zcu.intern_pool; const gpa = sema.gpa; const namespace = block.namespace; - const src_decl = zcu.declPtr(block.src_decl); - const src_node = src_decl.relativeToNodeIndex(src.node_offset.x); - 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) { - .anon => { - // It would be neat to have "struct:line:column" but this name has - // to survive incremental updates, where it may have been shifted down - // or up to a different line, but unchanged, and thus not unnecessarily - // semantically analyzed. - // This name is also used as the key in the parent namespace so it cannot be - // renamed. - - const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{ - src_decl.name.fmt(ip), anon_prefix, @intFromEnum(new_decl_index), - }, .no_embedded_nulls) catch unreachable; - try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); - return new_decl_index; - }, + .anon => {}, // handled after switch .parent => { - const name = zcu.declPtr(block.src_decl).name; - try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); + try zcu.initNewAnonDecl(new_decl_index, src_line, val, block.type_name_ctx); return new_decl_index; }, - .func => { + .func => func_strat: { const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip)); const zir_tags = sema.code.instructions.items(.tag); @@ -2915,7 +2887,7 @@ fn createAnonymousDeclTypeNamed( defer buf.deinit(); const writer = buf.writer(); - try writer.print("{}(", .{zcu.declPtr(block.src_decl).name.fmt(ip)}); + try writer.print("{}(", .{block.type_name_ctx.fmt(ip)}); var arg_i: usize = 0; for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) { @@ -2926,8 +2898,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 - return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null); + const arg_val = try sema.resolveValue(arg) orelse break :func_strat; // fall through to anon strat if (arg_i != 0) try writer.writeByte(','); @@ -2950,7 +2921,7 @@ fn createAnonymousDeclTypeNamed( try writer.writeByte(')'); const name = try ip.getOrPutString(gpa, buf.items, .no_embedded_nulls); - try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); + try zcu.initNewAnonDecl(new_decl_index, src_line, val, name); return new_decl_index; }, .dbg_var => { @@ -2962,16 +2933,31 @@ fn createAnonymousDeclTypeNamed( if (zir_data[i].str_op.operand != ref) continue; const name = try ip.getOrPutStringFmt(gpa, "{}.{s}", .{ - src_decl.name.fmt(ip), zir_data[i].str_op.getStr(sema.code), + block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code), }, .no_embedded_nulls); - try zcu.initNewAnonDecl(new_decl_index, src_decl.src_line, val, name); + try zcu.initNewAnonDecl(new_decl_index, src_line, val, name); return new_decl_index; }, else => {}, }; - return sema.createAnonymousDeclTypeNamed(block, src, val, .anon, anon_prefix, null); + // fall through to anon strat }, } + + // anon strat handling. + + // It would be neat to have "struct:line:column" but this name has + // to survive incremental updates, where it may have been shifted down + // or up to a different line, but unchanged, and thus not unnecessarily + // semantically analyzed. + // This name is also used as the key in the parent namespace so it cannot be + // renamed. + + const name = ip.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{ + block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index), + }, .no_embedded_nulls) catch unreachable; + try zcu.initNewAnonDecl(new_decl_index, src_line, val, name); + return new_decl_index; } fn zirEnumDecl( @@ -2990,8 +2976,9 @@ fn zirEnumDecl( const extra = sema.code.extraData(Zir.Inst.EnumDecl, extended.operand); var extra_index: usize = extra.end; - const src = extra.data.src(); - const tag_ty_src: LazySrcLoc = .{ .node_offset_container_tag = src.node_offset.x }; + 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]); @@ -3051,7 +3038,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, } }, }; @@ -3071,11 +3058,11 @@ fn zirEnumDecl( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, Value.fromInterned(wip_ty.index), small.name_strategy, "enum", inst, + extra.data.src_line, ); const new_decl = mod.declPtr(new_decl_index); new_decl.owns_tv = true; @@ -3132,11 +3119,12 @@ fn zirEnumDecl( var enum_block: Block = .{ .parent = null, .sema = sema, - .src_decl = new_decl_index, .namespace = new_namespace_index.unwrap() orelse block.namespace, .instructions = .{}, .inlining = null, .is_comptime = true, + .src_base_inst = tracked_inst, + .type_name_ctx = new_decl.name, }; defer enum_block.instructions.deinit(sema.gpa); @@ -3145,9 +3133,9 @@ fn zirEnumDecl( } if (tag_type_ref != .none) { - const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref); + const ty = try sema.resolveType(&enum_block, tag_ty_src, tag_type_ref); if (ty.zigTypeTag(mod) != .Int and ty.zigTypeTag(mod) != .ComptimeInt) { - return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)}); + return sema.fail(&enum_block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)}); } break :ty ty; } else if (fields_len == 0) { @@ -3184,36 +3172,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); @@ -3228,12 +3213,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); @@ -3248,11 +3235,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); @@ -3279,7 +3262,8 @@ fn zirUnionDecl( const extra = sema.code.extraData(Zir.Inst.UnionDecl, extended.operand); var extra_index: usize = extra.end; - const src = extra.data.src(); + 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: { @@ -3327,7 +3311,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, } }, }; @@ -3342,11 +3326,11 @@ fn zirUnionDecl( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, Value.fromInterned(wip_ty.index), small.name_strategy, "union", inst, + extra.data.src_line, ); mod.declPtr(new_decl_index).owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -3394,7 +3378,8 @@ fn zirOpaqueDecl( const extra = sema.code.extraData(Zir.Inst.OpaqueDecl, extended.operand); var extra_index: usize = extra.end; - const src = extra.data.src(); + 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]; @@ -3414,7 +3399,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, } }, }; @@ -3430,11 +3415,11 @@ fn zirOpaqueDecl( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, Value.fromInterned(wip_ty.index), small.name_strategy, "opaque", inst, + extra.data.src_line, ); mod.declPtr(new_decl_index).owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -3525,7 +3510,7 @@ fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; const operand = try sema.resolveInst(inst_data.operand); - return sema.analyzeRef(block, inst_data.src(), operand); + return sema.analyzeRef(block, block.tokenOffset(inst_data.src_tok), operand); } fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { @@ -3534,7 +3519,7 @@ fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; const operand = try sema.resolveInst(inst_data.operand); - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); return sema.ensureResultUsed(block, sema.typeOf(operand), src); } @@ -3551,19 +3536,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); @@ -3578,15 +3563,15 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com 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 src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand_ty = sema.typeOf(operand); switch (operand_ty.zigTypeTag(mod)) { .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); @@ -3601,7 +3586,7 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); const err_union_ty = if (operand_ty.zigTypeTag(mod) == .Pointer) @@ -3612,9 +3597,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); @@ -3626,7 +3611,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const object = try sema.resolveInst(inst_data.operand); return indexablePtrLen(sema, block, src, object); @@ -3668,8 +3653,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; @@ -3745,7 +3730,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); } @@ -3811,7 +3796,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)}); } @@ -3980,7 +3965,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: { @@ -3993,7 +3978,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: { @@ -4006,7 +3991,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(); }, @@ -4028,14 +4013,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); } @@ -4138,7 +4123,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); @@ -4161,7 +4146,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); @@ -4220,8 +4205,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com const mod = sema.mod; const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); - const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; + const src = block.nodeOffset(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(); @@ -4361,7 +4346,7 @@ fn zirForLen(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.MultiOp, inst_data.payload_index); const args = sema.code.refSlice(extra.end, extra.data.operands_len); - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); var len: Air.Inst.Ref = .none; var len_val: ?Value = null; @@ -4384,20 +4369,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; @@ -4417,16 +4402,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; @@ -4446,7 +4431,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); @@ -4459,11 +4444,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), }); } @@ -4504,16 +4489,16 @@ fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcL fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; const ptr = try sema.resolveInst(un_node.operand); - return sema.optEuBasePtrInit(block, ptr, un_node.src()); + return sema.optEuBasePtrInit(block, ptr, block.nodeOffset(un_node.src_node)); } fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const mod = sema.mod; const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = pl_node.src(); + 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, }; @@ -4561,7 +4546,7 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const mod = sema.mod; const un_tok = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; - const src = un_tok.src(); + const src = block.tokenOffset(un_tok.src_tok); // In case of GenericPoison, we don't actually have a type, so this will be // treated as an untyped address-of operator. const operand_air_inst = sema.resolveInst(un_tok.operand) catch |err| switch (err) { @@ -4575,9 +4560,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; }); } @@ -4590,9 +4575,9 @@ fn zirValidateArrayInitRefTy( ) CompileError!Air.Inst.Ref { const mod = sema.mod; const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = pl_node.src(); + 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, }; @@ -4632,8 +4617,8 @@ fn zirValidateArrayInitTy( ) CompileError!void { const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - const ty_src: LazySrcLoc = if (is_result_ty) src else .{ .node_offset_init_ty = inst_data.src_node }; + const src = block.nodeOffset(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. @@ -4695,7 +4680,7 @@ fn zirValidateStructInitTy( ) CompileError!void { const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const ty = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) { // It's okay for the type to be unknown: this will result in an anonymous struct init. error.GenericPoison => return, @@ -4720,7 +4705,7 @@ fn zirValidatePtrStructInit( const mod = sema.mod; const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const init_src = validate_inst.src(); + const init_src = block.nodeOffset(validate_inst.src_node); const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); const instrs = sema.code.bodySlice(validate_extra.end, validate_extra.data.body_len); const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node; @@ -4759,7 +4744,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", .{}, @@ -4768,8 +4752,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; @@ -4786,7 +4770,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, @@ -4895,15 +4879,15 @@ fn validateUnionInit( try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store); return; } else if (try sema.typeRequiresComptime(union_ty)) { - return sema.failWithNeededComptime(block, field_ptr_data.src(), .{ + return sema.failWithNeededComptime(block, block.nodeOffset(field_ptr_data.src_node), .{ .needed_comptime_reason = "initializer of comptime only union must be comptime-known", }); } - if (init_ref) |v| try sema.validateRuntimeValue(block, field_ptr_data.src(), v); + if (init_ref) |v| try sema.validateRuntimeValue(block, block.nodeOffset(field_ptr_data.src_node), v); 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( @@ -4929,7 +4913,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( @@ -4966,18 +4950,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; } @@ -4992,16 +4976,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); } @@ -5086,7 +5061,7 @@ fn validateStructInit( field_values[i] = val.toIntern(); } else if (require_comptime) { const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(field_ptr)].pl_node; - return sema.failWithNeededComptime(block, field_ptr_data.src(), .{ + return sema.failWithNeededComptime(block, block.nodeOffset(field_ptr_data.src_node), .{ .needed_comptime_reason = "initializer of comptime only struct must be comptime-known", }); } else { @@ -5103,18 +5078,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; } @@ -5122,21 +5097,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); } @@ -5210,7 +5176,7 @@ fn zirValidatePtrArrayInit( ) CompileError!void { const mod = sema.mod; const validate_inst = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const init_src = validate_inst.src(); + const init_src = block.nodeOffset(validate_inst.src_node); const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); const instrs = sema.code.bodySlice(validate_extra.end, validate_extra.data.body_len); const first_elem_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node; @@ -5238,9 +5204,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; } @@ -5415,7 +5381,7 @@ fn zirValidatePtrArrayInit( fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); @@ -5440,15 +5406,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); @@ -5459,8 +5423,8 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp const mod = sema.mod; 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 = inst_data.src(); - const destructure_src = LazySrcLoc.nodeOffset(extra.destructure_node); + const src = block.nodeOffset(inst_data.src_node); + const destructure_src = block.nodeOffset(extra.destructure_node); const operand = try sema.resolveInst(extra.operand); const operand_ty = sema.typeOf(operand); @@ -5472,21 +5436,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; }); } @@ -5521,24 +5485,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); @@ -5547,25 +5511,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); @@ -5573,16 +5537,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 { @@ -5590,7 +5553,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi defer tracy.end(); const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = pl_node.src(); + const src = block.nodeOffset(pl_node.src_node); const bin = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data; const ptr = try sema.resolveInst(bin.lhs); const operand = try sema.resolveInst(bin.rhs); @@ -5672,7 +5635,7 @@ fn storeToInferredAllocComptime( fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const quota: u32 = @intCast(try sema.resolveInt(block, src, inst_data.operand, Type.u32, .{ .needed_comptime_reason = "eval branch quota must be comptime-known", })); @@ -5687,7 +5650,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v const zir_tags = sema.code.instructions.items(.tag); const zir_datas = sema.code.instructions.items(.data); const inst_data = zir_datas[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const ptr = try sema.resolveInst(extra.lhs); const operand = try sema.resolveInst(extra.rhs); @@ -5707,8 +5670,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()) @@ -5821,8 +5784,8 @@ fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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", }); @@ -5831,6 +5794,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; @@ -5863,20 +5827,21 @@ 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; } fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const msg_inst = try sema.resolveInst(inst_data.operand); // `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", .{}); @@ -5886,7 +5851,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); @@ -5898,7 +5863,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = parent_block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); const body = sema.code.bodySlice(extra.end, extra.data.body_len); const gpa = sema.gpa; @@ -5933,7 +5898,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; @@ -5971,7 +5936,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr const comp = mod.comp; const gpa = sema.gpa; const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = pl_node.src(); + const src = parent_block.nodeOffset(pl_node.src_node); const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index); const body = sema.code.bodySlice(extra.end, extra.data.body_len); @@ -5982,14 +5947,10 @@ 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, - .src_decl = parent_block.src_decl, .namespace = parent_block.namespace, .instructions = .{}, .inlining = parent_block.inlining, @@ -5999,6 +5960,8 @@ 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, + .type_name_ctx = parent_block.type_name_ctx, }; defer child_block.instructions.deinit(gpa); @@ -6010,11 +5973,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) { @@ -6073,7 +6036,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr fn zirSuspendBlock(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 = inst_data.src(); + const src = parent_block.nodeOffset(inst_data.src_node); return sema.failWithUseOfAsync(parent_block, src); } @@ -6082,7 +6045,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_compt defer tracy.end(); const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = pl_node.src(); + const src = parent_block.nodeOffset(pl_node.src_node); const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index); const body = sema.code.bodySlice(extra.end, extra.data.body_len); const gpa = sema.gpa; @@ -6109,7 +6072,6 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_compt var child_block: Block = .{ .parent = parent_block, .sema = sema, - .src_decl = parent_block.src_decl, .namespace = parent_block.namespace, .instructions = .{}, .label = &label, @@ -6124,6 +6086,8 @@ 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, + .type_name_ctx = parent_block.type_name_ctx, }; defer child_block.instructions.deinit(gpa); @@ -6318,14 +6282,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; }; @@ -6417,9 +6380,9 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void const mod = sema.mod; 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 = inst_data.src(); - 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 src = block.nodeOffset(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), @@ -6433,13 +6396,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); @@ -6457,9 +6414,9 @@ fn zirExportValue(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 extra = sema.code.extraData(Zir.Inst.ExportValue, inst_data.payload_index).data; - const src = inst_data.src(); - 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 src = block.nodeOffset(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", }); @@ -6475,7 +6432,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, }); @@ -6500,11 +6456,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; @@ -6523,7 +6478,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, }); @@ -6563,8 +6517,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", .{ @@ -6583,9 +6537,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); @@ -6606,7 +6560,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", }); @@ -6616,7 +6570,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", }); @@ -6624,7 +6578,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", }); @@ -6634,7 +6588,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", }); @@ -6664,7 +6618,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); @@ -6774,21 +6728,21 @@ fn addDbgVar( fn zirDeclRef(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)].str_tok; - const src = inst_data.src(); + const src = block.tokenOffset(inst_data.src_tok); const decl_name = try mod.intern_pool.getOrPutString( sema.gpa, inst_data.get(sema.code), .no_embedded_nulls, ); const decl_index = try sema.lookupIdentifier(block, src, decl_name); - try sema.addReferencedBy(block, src, decl_index); + try sema.addReferencedBy(src, decl_index); return sema.analyzeDeclRef(decl_index); } fn zirDeclVal(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)].str_tok; - const src = inst_data.src(); + const src = block.tokenOffset(inst_data.src_tok); const decl_name = try mod.intern_pool.getOrPutString( sema.gpa, inst_data.get(sema.code), @@ -6891,12 +6845,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; }; @@ -6938,16 +6894,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, }; @@ -7055,8 +7011,8 @@ 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 call_src = inst_data.src(); + 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, .field => Zir.Inst.FieldCall, @@ -7077,7 +7033,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); }, }; @@ -7187,11 +7143,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); @@ -7217,7 +7173,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}", .{ @@ -7229,7 +7184,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); @@ -7337,18 +7297,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)), - } }, + } }), }; } @@ -7460,7 +7418,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 @@ -7482,8 +7439,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, }; } @@ -7530,7 +7486,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 } @@ -7562,14 +7517,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); @@ -7608,7 +7565,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), @@ -7622,12 +7578,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; }; @@ -7654,7 +7610,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), @@ -7749,7 +7704,6 @@ fn analyzeCall( var child_block: Block = .{ .parent = null, .sema = sema, - .src_decl = module_fn.owner_decl, .namespace = fn_owner_decl.src_namespace, .instructions = .{}, .label = null, @@ -7761,6 +7715,8 @@ 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().?, + .type_name_ctx = fn_owner_decl.name, }; const merges = &child_block.inlining.?.merges; @@ -7834,7 +7790,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; @@ -7849,7 +7805,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. @@ -7920,7 +7876,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. @@ -8081,7 +8037,7 @@ fn analyzeInlineCallArg( // Evaluate the parameter type expression now that previous ones have // been mapped, and coerce the corresponding argument to it. const pl_tok = ics.callee().code.instructions.items(.data)[@intFromEnum(inst)].pl_tok; - const param_src = pl_tok.src(); + const param_src = param_block.tokenOffset(pl_tok.src_tok); const extra = ics.callee().code.extraData(Zir.Inst.Param, pl_tok.payload_index); const param_body = ics.callee().code.bodySlice(extra.end, extra.data.body_len); const param_ty = param_ty: { @@ -8261,7 +8217,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, @@ -8271,11 +8226,12 @@ fn instantiateGenericCall( var child_block: Block = .{ .parent = null, .sema = &child_sema, - .src_decl = generic_owner_func.owner_decl, .namespace = namespace_index, .instructions = .{}, .inlining = null, .is_comptime = true, + .src_base_inst = fn_owner_decl.zir_decl_index.unwrap().?, + .type_name_ctx = fn_owner_decl.name, }; defer child_block.instructions.deinit(gpa); @@ -8306,22 +8262,23 @@ 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); - break :param_ty try child_sema.analyzeAsType(&child_block, param_data.src(), param_ty_inst); + break :param_ty try child_sema.analyzeAsType( + &child_block, + child_block.tokenOffset(param_data.src_tok), + param_ty_inst, + ); }, else => unreachable, } @@ -8353,14 +8310,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 = switch (param_tag) { - .param_comptime => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].pl_tok.src(), - .param_anytype_comptime => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.src(), + 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; }), @@ -8368,16 +8325,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 = switch (param_tag) { - .param => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].pl_tok.src(), - .param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.src(), + 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; }), @@ -8414,12 +8370,12 @@ 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); - try sema.addReferencedBy(block, call_src, callee.owner_decl); + try sema.addReferencedBy(call_src, callee.owner_decl); // Make a runtime call to the new function, making sure to omit the comptime args. const func_ty = Type.fromInterned(callee.ty); @@ -8501,7 +8457,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)}); @@ -8516,7 +8472,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 @@ -8539,7 +8495,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, }; @@ -8557,7 +8513,7 @@ fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai fn zirIndexablePtrElemType(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 src = un_node.src(); + const src = block.nodeOffset(un_node.src_node); const ptr_ty = sema.resolveType(block, src, un_node.operand) catch |err| switch (err) { error.GenericPoison => return .generic_poison_type, else => |e| return e, @@ -8573,7 +8529,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 @@ -8582,7 +8538,7 @@ fn zirVectorElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr else => |e| return e, }; if (!vec_ty.isVector(mod)) { - return sema.fail(block, un_node.src(), "expected vector type, found '{}'", .{vec_ty.fmt(mod)}); + return sema.fail(block, block.nodeOffset(un_node.src_node), "expected vector type, found '{}'", .{vec_ty.fmt(mod)}); } return Air.internedToRef(vec_ty.childType(mod).toIntern()); } @@ -8590,8 +8546,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", @@ -8611,8 +8567,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", }); @@ -8632,9 +8588,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", }); @@ -8669,10 +8625,10 @@ fn zirAnyframeType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; if (true) { - return sema.failWithUseOfAsync(block, inst_data.src()); + 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); @@ -8686,8 +8642,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); @@ -8739,8 +8695,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(); @@ -8782,8 +8738,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); @@ -8822,16 +8778,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); @@ -8885,8 +8841,8 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError fn zirIntFromEnum(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 src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -8943,8 +8899,8 @@ fn zirEnumFromInt(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 extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; - const src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -9012,7 +8968,7 @@ fn zirOptionalPayloadPtr( const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; const optional_ptr = try sema.resolveInst(inst_data.operand); - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); return sema.analyzeOptionalPayloadPtr(block, src, optional_ptr, safety_check, false); } @@ -9096,7 +9052,7 @@ fn zirOptionalPayload( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); const result_ty = switch (operand_ty.zigTypeTag(mod)) { @@ -9148,7 +9104,7 @@ fn zirErrUnionPayload( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); const operand_src = src; const err_union_ty = sema.typeOf(operand); @@ -9201,7 +9157,7 @@ fn zirErrUnionPayloadPtr( const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; const operand = try sema.resolveInst(inst_data.operand); - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); return sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); } @@ -9285,7 +9241,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); return sema.analyzeErrUnionCode(block, src, operand); } @@ -9318,7 +9274,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); return sema.analyzeErrUnionCodePtr(block, src, operand); } @@ -9360,7 +9316,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; @@ -9396,13 +9352,17 @@ fn zirFunc( src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data; } - // If this instruction has a body it means it's the type of the `owner_decl` - // otherwise it's a function type without a `callconv` attribute and should - // never be `.C`. - const cc: std.builtin.CallingConvention = if (has_body and mod.declPtr(block.src_decl).is_exported) - .C - else - .Unspecified; + // If this instruction has a body, then it's a function declaration, and we decide + // the callconv based on whether it is exported. Otherwise, the callconv defaults + // to `.Unspecified`. + const cc: std.builtin.CallingConvention = if (has_body) cc: { + const fn_is_exported = if (sema.generic_owner != .none) exported: { + const generic_owner_fn = mod.funcInfo(sema.generic_owner); + const generic_owner_decl = mod.declPtr(generic_owner_fn.owner_decl); + break :exported generic_owner_decl.is_exported; + } else sema.owner_decl.is_exported; + break :cc if (fn_is_exported) .C else .Unspecified; + } else .Unspecified; return sema.funcCommon( block, @@ -9441,18 +9401,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; @@ -9562,9 +9519,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); @@ -9604,9 +9561,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 @@ -9635,11 +9592,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 @@ -9660,13 +9616,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; @@ -9675,13 +9630,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; @@ -9842,9 +9796,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, @@ -9956,13 +9910,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; @@ -9978,12 +9931,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); @@ -9994,16 +9946,16 @@ fn finishFunc( param_body[0..block.params.len], ) |is_comptime, name_nts, param_index| { if (!is_comptime) { - const param_src = switch (tags[@intFromEnum(param_index)]) { - .param => data[@intFromEnum(param_index)].pl_tok.src(), - .param_anytype => data[@intFromEnum(param_index)].str_tok.src(), + const param_src = block.tokenOffset(switch (tags[@intFromEnum(param_index)]) { + .param => data[@intFromEnum(param_index)].pl_tok.src_tok, + .param_anytype => data[@intFromEnum(param_index)].str_tok.src_tok, else => unreachable, - }; + }); 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", .{}); } } } @@ -10081,7 +10033,7 @@ fn zirParam( comptime_syntax: bool, ) CompileError!void { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok; - const src = inst_data.src(); + const src = block.tokenOffset(inst_data.src_tok); const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index); const param_name: Zir.NullTerminatedString = extra.data.name; const body = sema.code.bodySlice(extra.end, extra.data.body_len); @@ -10093,18 +10045,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| { @@ -10191,7 +10140,7 @@ fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data; return sema.analyzeAs(block, src, extra.dest_type, extra.operand, false); } @@ -10201,7 +10150,7 @@ fn zirAsShiftOperand(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.As, inst_data.payload_index).data; return sema.analyzeAs(block, src, extra.dest_type, extra.operand, true); } @@ -10246,7 +10195,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); @@ -10257,10 +10206,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); @@ -10298,7 +10246,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! .storage = .{ .elems = new_elems }, } })); } - try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src); + try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), ptr_src); try sema.validateRuntimeValue(block, ptr_src, operand); if (!is_vector) { return block.addUnOp(.int_from_ptr, operand); @@ -10320,8 +10268,8 @@ 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 = inst_data.src(); - const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node }; + const src = block.nodeOffset(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, @@ -10338,8 +10286,8 @@ 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 = inst_data.src(); - const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node }; + const src = block.nodeOffset(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, @@ -10356,8 +10304,8 @@ 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 = inst_data.src(); - const field_name_src: LazySrcLoc = .{ .node_offset_field_name_init = inst_data.src_node }; + const src = block.nodeOffset(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, @@ -10381,8 +10329,8 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; + const src = block.nodeOffset(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, .{ @@ -10396,8 +10344,8 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; + const src = block.nodeOffset(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, .{ @@ -10411,14 +10359,14 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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"); const operand = try sema.resolveInst(extra.rhs); - return sema.intCast(block, inst_data.src(), dest_ty, src, operand, operand_src, true); + return sema.intCast(block, block.nodeOffset(inst_data.src_node), dest_ty, src, operand, operand_src, true); } fn intCast( @@ -10581,8 +10529,8 @@ 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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"); @@ -10608,10 +10556,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 => {}, } @@ -10622,11 +10570,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 => {}, } @@ -10672,10 +10620,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 => {}, } @@ -10685,11 +10633,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 => {}, } @@ -10715,7 +10663,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air .Vector, => {}, } - return sema.bitCast(block, dest_ty, operand, inst_data.src(), operand_src); + return sema.bitCast(block, dest_ty, operand, block.nodeOffset(inst_data.src_node), operand_src); } fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -10724,8 +10672,8 @@ 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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"); @@ -10778,7 +10726,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A if (dest_is_comptime_float) { return sema.fail(block, operand_src, "unable to cast runtime value to 'comptime_float'", .{}); } - try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); + try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), operand_src); const src_bits = operand_scalar_ty.floatBits(target); const dst_bits = dest_scalar_ty.floatBits(target); @@ -10803,7 +10751,7 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(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 elem_index = try sema.resolveInst(extra.rhs); @@ -10815,8 +10763,8 @@ fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -10832,7 +10780,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 { @@ -10841,20 +10789,20 @@ fn zirElemPtr(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 = inst_data.src(); + const src = block.nodeOffset(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 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; }; @@ -10868,8 +10816,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -10883,7 +10831,7 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; const array_ptr = try sema.resolveInst(extra.ptr); const elem_index = try sema.mod.intRef(Type.usize, extra.index); @@ -10902,15 +10850,15 @@ fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); 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 { @@ -10918,16 +10866,16 @@ fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data; 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 { @@ -10935,16 +10883,16 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - const sentinel_src: LazySrcLoc = .{ .node_offset_slice_sentinel = inst_data.src_node }; + const src = block.nodeOffset(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); } @@ -10954,19 +10902,19 @@ fn zirSliceLength(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data; const array_ptr = try sema.resolveInst(extra.lhs); 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); } @@ -11000,8 +10948,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, @@ -11014,10 +10962,12 @@ const SwitchProngAnalysis = struct { merges: *Block.Merges, ) CompileError!Air.Inst.Ref { const sema = spa.sema; - const src = sema.code.instructions.items(.data)[@intFromEnum(spa.switch_block_inst)].pl_node.src(); + const src = spa.parent_block.nodeOffset( + sema.code.instructions.items(.data)[@intFromEnum(spa.switch_block_inst)].pl_node.src_node, + ); 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)); @@ -11032,7 +10982,7 @@ const SwitchProngAnalysis = struct { child_block, capture == .by_ref, prong_type == .special, - raw_capture_src, + capture_src, case_vals, inline_case_capture, ); @@ -11058,8 +11008,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, @@ -11073,7 +11023,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)); @@ -11088,7 +11038,7 @@ const SwitchProngAnalysis = struct { case_block, capture == .by_ref, prong_type == .special, - raw_capture_src, + capture_src, case_vals, inline_case_capture, ); @@ -11109,23 +11059,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), }); } @@ -11138,7 +11083,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 { @@ -11151,10 +11096,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).?; @@ -11195,7 +11140,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, @@ -11205,14 +11150,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).?; } @@ -11232,27 +11177,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, }; @@ -11280,28 +11220,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, }; @@ -11336,7 +11271,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; } } @@ -11359,7 +11294,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); } } @@ -11388,20 +11323,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); @@ -11455,7 +11389,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, @@ -11465,7 +11398,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); } @@ -11473,7 +11406,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()); @@ -11527,10 +11460,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; }; @@ -11554,7 +11487,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()); @@ -11563,13 +11496,13 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp const mod = sema.mod; const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const switch_src = inst_data.src(); + 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); @@ -11675,7 +11608,6 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp var child_block: Block = .{ .parent = block, .sema = sema, - .src_decl = block.src_decl, .namespace = block.namespace, .instructions = .{}, .label = &label, @@ -11689,6 +11621,8 @@ 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, + .type_name_ctx = block.type_name_ctx, }; const merges = &child_block.label.?.merges; defer child_block.instructions.deinit(gpa); @@ -11755,6 +11689,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, @@ -11796,7 +11731,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); @@ -11871,10 +11806,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r const mod = sema.mod; const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + 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: { @@ -11941,7 +11876,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; @@ -11964,21 +11899,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'", @@ -11993,7 +11925,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. @@ -12013,8 +11945,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 }, + } }), )); } } @@ -12038,8 +11973,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) }, + } }), )); } @@ -12060,7 +11998,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", .{}, @@ -12078,8 +12015,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)}, @@ -12123,8 +12060,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 }, + } }), )); } } @@ -12147,8 +12087,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) }, + } }), )); } @@ -12166,8 +12109,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]); @@ -12218,8 +12164,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 }, + } }), )); } } @@ -12242,8 +12191,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) }, + } }), )); } @@ -12301,8 +12253,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 }, + } }), )); } } @@ -12325,8 +12280,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) }, + } }), )); } @@ -12382,7 +12340,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r var child_block: Block = .{ .parent = block, .sema = sema, - .src_decl = block.src_decl, .namespace = block.namespace, .instructions = .{}, .label = &label, @@ -12396,6 +12353,8 @@ 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, + .type_name_ctx = block.type_name_ctx, }; const merges = &child_block.label.?.merges; defer child_block.instructions.deinit(gpa); @@ -12409,6 +12368,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, @@ -12441,7 +12401,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, @@ -12508,9 +12471,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, @@ -12531,7 +12494,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); @@ -12553,7 +12516,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; @@ -12567,7 +12530,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, @@ -12622,8 +12588,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. @@ -12639,17 +12605,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( @@ -12657,7 +12617,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, @@ -12680,22 +12643,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) { @@ -12704,7 +12661,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, @@ -12734,7 +12694,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 @@ -12751,7 +12711,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, @@ -12835,7 +12798,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, @@ -12900,7 +12866,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, @@ -12945,7 +12914,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, @@ -12976,7 +12948,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, @@ -13004,7 +12979,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, @@ -13030,7 +13008,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, @@ -13080,7 +13061,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, @@ -13140,6 +13124,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, @@ -13160,7 +13145,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( @@ -13168,7 +13153,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, @@ -13194,7 +13182,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( @@ -13202,7 +13190,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, @@ -13218,8 +13209,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))) { @@ -13229,7 +13220,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, @@ -13251,7 +13245,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, @@ -13337,36 +13334,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: { @@ -13393,7 +13373,7 @@ fn validateErrSetSwitch( const ip = &mod.intern_pool; const src_node_offset = inst_data.src_node; - const src = inst_data.src(); + const src = block.nodeOffset(src_node_offset); var extra_index: usize = else_case.end; { @@ -13409,8 +13389,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 }, + } }), )); } } @@ -13433,8 +13416,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) }, + } }), )); } @@ -13463,7 +13449,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", .{}, @@ -13472,7 +13457,6 @@ fn validateErrSetSwitch( }; try sema.errNote( - block, src, msg, "unhandled error value: 'error.{}'", @@ -13550,18 +13534,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 }; } @@ -13571,36 +13561,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; } @@ -13610,50 +13598,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( @@ -13662,25 +13641,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, @@ -13688,12 +13663,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; } @@ -13707,19 +13681,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", @@ -13833,7 +13805,7 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I } } else return; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable"; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); if (try sema.resolveDefinedValue(block, src, operand)) |val| { if (val.getErrorName(sema.mod).unwrap()) |name| { @@ -13846,8 +13818,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", @@ -13897,9 +13869,9 @@ fn zirHasDecl(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.Bin, inst_data.payload_index).data; - const src = inst_data.src(); - 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 src = block.nodeOffset(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", @@ -13929,7 +13901,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; - const operand_src = inst_data.src(); + const operand_src = block.tokenOffset(inst_data.src_tok); const operand = inst_data.get(sema.code); const result = mod.importFile(block.getFileScope(mod), operand) catch |err| switch (err) { @@ -13958,7 +13930,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", }); @@ -13967,8 +13939,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}); }, @@ -14009,9 +13980,9 @@ fn zirShl( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - 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.nodeOffset(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); @@ -14179,9 +14150,9 @@ fn zirShr( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); - 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.nodeOffset(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); @@ -14314,9 +14285,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); @@ -14368,8 +14339,8 @@ 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -14415,7 +14386,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); @@ -14442,10 +14413,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; @@ -14456,10 +14427,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; @@ -14487,18 +14458,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); } @@ -14517,7 +14488,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const rhs = try sema.resolveInst(extra.rhs); const lhs_ty = sema.typeOf(lhs); const rhs_ty = sema.typeOf(rhs); - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const lhs_is_tuple = lhs_ty.isTuple(mod); const rhs_is_tuple = rhs_ty.isTuple(mod); @@ -14525,8 +14496,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); @@ -14638,10 +14609,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(); @@ -14651,10 +14622,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(); @@ -14683,10 +14654,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); } @@ -14695,10 +14666,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); } @@ -14717,20 +14688,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); } @@ -14792,8 +14763,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 @@ -14810,10 +14781,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 @@ -14845,10 +14816,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; @@ -14868,10 +14839,10 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data; const uncoerced_lhs = try sema.resolveInst(extra.lhs); const uncoerced_lhs_ty = sema.typeOf(uncoerced_lhs); - const src: LazySrcLoc = inst_data.src(); - 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 src: LazySrcLoc = block.nodeOffset(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 @@ -14920,11 +14891,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 => {}, } @@ -15038,9 +15009,9 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai fn zirNegate(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 src = inst_data.src(); + 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); @@ -15070,9 +15041,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. fn zirNegateWrap(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 src = inst_data.src(); + 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); @@ -15098,9 +15069,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); @@ -15111,9 +15082,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); @@ -15276,9 +15247,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); @@ -15441,9 +15412,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); @@ -15551,9 +15522,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); @@ -15792,9 +15763,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); @@ -15976,9 +15947,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); @@ -16071,9 +16042,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); @@ -16173,10 +16144,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); @@ -16988,7 +16959,7 @@ fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.In defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const ptr_src = src; // TODO better source location const ptr = try sema.resolveInst(inst_data.operand); return sema.analyzeLoad(block, src, ptr, ptr_src); @@ -17004,8 +16975,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); @@ -17178,9 +17149,9 @@ fn zirCmpEq( 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 src: LazySrcLoc = inst_data.src(); - 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: LazySrcLoc = block.nodeOffset(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); @@ -17259,9 +17230,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); @@ -17294,9 +17265,9 @@ 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 = inst_data.src(); - 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: LazySrcLoc = block.nodeOffset(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); @@ -17438,7 +17409,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, @@ -17481,7 +17452,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, @@ -17525,7 +17496,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); } @@ -17535,7 +17506,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), @@ -17549,7 +17520,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}", .{ @@ -17557,15 +17529,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 @@ -17577,7 +17549,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}", .{ @@ -17585,18 +17557,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; @@ -17628,7 +17600,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); } @@ -17721,7 +17693,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const gpa = sema.gpa; const ip = &mod.intern_pool; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const ty = try sema.resolveType(block, src, inst_data.operand); const type_info_ty = try sema.getBuiltinType("Type"); const type_info_tag_ty = type_info_ty.unionTagType(mod).?; @@ -18884,7 +18856,6 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr var child_block: Block = .{ .parent = block, .sema = sema, - .src_decl = block.src_decl, .namespace = block.namespace, .instructions = .{}, .inlining = block.inlining, @@ -18892,6 +18863,8 @@ 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, + .type_name_ctx = block.type_name_ctx, }; defer child_block.instructions.deinit(sema.gpa); @@ -18903,7 +18876,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr fn zirTypeofLog2IntType(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 = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); const res_ty = try sema.log2IntType(block, operand_ty, src); @@ -18956,13 +18929,12 @@ 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 = .{ .parent = block, .sema = sema, - .src_decl = block.src_decl, .namespace = block.namespace, .instructions = .{}, .inlining = block.inlining, @@ -18971,6 +18943,8 @@ fn zirTypeofPeer( .runtime_cond = block.runtime_cond, .runtime_loop = block.runtime_loop, .runtime_index = block.runtime_index, + .src_base_inst = block.src_base_inst, + .type_name_ctx = block.type_name_ctx, }; defer child_block.instructions.deinit(sema.gpa); // Ignore the result, we only care about the instructions in `args`. @@ -18995,8 +18969,8 @@ 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -19027,8 +19001,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); @@ -19059,7 +19033,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); @@ -19152,7 +19126,7 @@ fn zirIsNonNull( defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); try sema.checkNullableType(block, src, sema.typeOf(operand)); return sema.analyzeIsNull(block, src, operand, true); @@ -19168,7 +19142,7 @@ fn zirIsNonNullPtr( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const ptr = try sema.resolveInst(inst_data.operand); try sema.checkNullableType(block, src, sema.typeOf(ptr).elemType2(mod)); if ((try sema.resolveValue(ptr)) == null) { @@ -19193,7 +19167,7 @@ fn zirIsNonErr(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 src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); try sema.checkErrorType(block, src, sema.typeOf(operand)); return sema.analyzeIsNonErr(block, src, operand); @@ -19205,7 +19179,7 @@ fn zirIsNonErrPtr(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 = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const ptr = try sema.resolveInst(inst_data.operand); try sema.checkErrorType(block, src, sema.typeOf(ptr).elemType2(mod)); const loaded = try sema.analyzeLoad(block, src, ptr, src); @@ -19217,7 +19191,7 @@ fn zirRetIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); return sema.analyzeIsNonErr(block, src, operand); } @@ -19232,7 +19206,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); @@ -19255,7 +19229,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); @@ -19299,8 +19273,8 @@ 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; + const src = parent_block.nodeOffset(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); @@ -19346,8 +19320,8 @@ 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; + const src = parent_block.nodeOffset(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); @@ -19437,12 +19411,13 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label .block = .{ .parent = block, .sema = sema, - .src_decl = block.src_decl, .namespace = block.namespace, .instructions = .{}, .label = &labeled_block.label, .inlining = block.inlining, .is_comptime = block.is_comptime, + .src_base_inst = block.src_base_inst, + .type_name_ctx = block.type_name_ctx, }, }; sema.post_hoc_blocks.putAssumeCapacityNoClobber(new_block_inst, labeled_block); @@ -19471,17 +19446,17 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable"; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); if (block.is_comptime) { 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, @@ -19495,13 +19470,13 @@ fn zirRetErrValue( ) CompileError!void { const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; + const src = block.tokenOffset(inst_data.src_tok); const err_name = try mod.intern_pool.getOrPutString( sema.gpa, inst_data.get(sema.code), .no_embedded_nulls, ); _ = try mod.getErrorValue(err_name); - const src = inst_data.src(); // Return the error code from the function. const error_set_type = try mod.singleErrorSetType(err_name); const result_inst = Air.internedToRef((try mod.intern(.{ .err = .{ @@ -19521,38 +19496,38 @@ fn zirRetImplicit( const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok; - const r_brace_src = inst_data.src(); + const r_brace_src = block.tokenOffset(inst_data.src_tok); if (block.inlining == null and sema.func_is_naked) { assert(!block.is_comptime); if (block.wantSafety()) { // 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); @@ -19567,9 +19542,9 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; const operand = try sema.resolveInst(inst_data.operand); - const src = inst_data.src(); + 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 { @@ -19577,12 +19552,12 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const ret_ptr = try sema.resolveInst(inst_data.operand); 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)) { @@ -19676,7 +19651,7 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { const extra = sema.code.extraData(Zir.Inst.RestoreErrRetIndex, extended.operand).data; - return sema.restoreErrRetIndex(start_block, extra.src(), extra.block, extra.operand); + return sema.restoreErrRetIndex(start_block, start_block.nodeOffset(extra.src_node), extra.block, extra.operand); } /// If `operand` is non-error (or is `none`), restores the error return trace to @@ -19795,9 +19770,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; } @@ -19811,10 +19784,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); @@ -19850,18 +19823,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; }; @@ -19953,11 +19926,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; @@ -19971,10 +19943,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; }); } @@ -20003,8 +19974,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); - const ty_src: LazySrcLoc = .{ .node_offset_init_ty = inst_data.src_node }; + const src = block.nodeOffset(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; @@ -20023,7 +19994,7 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const ty_operand = sema.resolveType(block, src, inst_data.operand) catch |err| switch (err) { // Generic poison means this is an untyped anonymous empty struct init error.GenericPoison => return .empty_struct, @@ -20098,9 +20069,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) { @@ -20155,7 +20126,7 @@ fn zirStructInit( const zir_datas = sema.code.instructions.items(.data); const inst_data = zir_datas[@intFromEnum(inst)].pl_node; const extra = sema.code.extraData(Zir.Inst.StructInit, inst_data.payload_index); - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const mod = sema.mod; const ip = &mod.intern_pool; @@ -20194,7 +20165,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, @@ -20235,7 +20206,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, @@ -20249,7 +20220,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", .{ @@ -20327,16 +20298,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; } @@ -20346,18 +20313,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 { @@ -20370,16 +20337,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; } @@ -20392,16 +20355,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 { @@ -20413,16 +20376,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); } @@ -20449,9 +20403,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", }); } @@ -20479,15 +20434,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); @@ -20500,7 +20450,7 @@ fn zirStructInitAnon( inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.StructInitAnon, inst_data.payload_index); return sema.structInitAnon(block, src, .anon_init, extra.data, extra.end, false); } @@ -20555,9 +20505,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.*)); @@ -20589,15 +20541,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(); @@ -20652,7 +20599,7 @@ fn zirArrayInit( const mod = sema.mod; const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); const args = sema.code.refSlice(extra.end, extra.data.operands_len); @@ -20676,15 +20623,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); @@ -20701,29 +20652,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); } } @@ -20756,15 +20695,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) { @@ -20815,7 +20749,7 @@ fn zirArrayInitAnon( inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); const operands = sema.code.refSlice(extra.end, extra.data.operands_len); return sema.arrayInitAnon(block, src, operands, false); @@ -20843,7 +20777,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])); @@ -20914,8 +20848,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", @@ -20928,8 +20862,8 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp const ip = &mod.intern_pool; 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 = inst_data.src(); - const field_name_src: LazySrcLoc = .{ .node_offset_field_name_init = inst_data.src_node }; + const ty_src = block.nodeOffset(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 @@ -20969,7 +20903,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); }, @@ -20978,7 +20912,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); }, @@ -21029,14 +20963,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)}); @@ -21051,7 +20985,7 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air fn zirIntFromBool(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 src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); const operand = try sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); const is_vector = operand_ty.zigTypeTag(mod) == .Vector; @@ -21100,7 +21034,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); @@ -21122,7 +21056,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); @@ -21190,7 +21124,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); @@ -21212,8 +21146,8 @@ 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 src = inst_data.src(); + 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); const mod = sema.mod; @@ -21222,7 +21156,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); }, @@ -21245,13 +21179,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); @@ -21281,11 +21214,23 @@ fn zirReify( const gpa = sema.gpa; 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 extra = sema.code.extraData(Zir.Inst.Reify, extended.operand).data; + 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 operand_src: LazySrcLoc = .{ + .base_node_inst = tracked_inst, + .offset = .{ + .node_offset_builtin_call_arg = .{ + .builtin_call_node = 0, // `tracked_inst` is precisely the `reify` instruction, so offset is 0 + .arg_index = 0, + }, + }, + }; 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 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", @@ -21438,11 +21383,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; @@ -21602,7 +21546,7 @@ fn zirReify( .needed_comptime_reason = "struct fields must be comptime-known", }); - return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy, is_tuple_val.toBool()); + return try sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy, is_tuple_val.toBool(), extra.src_line); }, .Enum => { const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); @@ -21631,7 +21575,7 @@ fn zirReify( .needed_comptime_reason = "enum fields must be comptime-known", }); - return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_arr, name_strategy); + return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_arr, name_strategy, extra.src_line); }, .Opaque => { const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); @@ -21658,11 +21602,11 @@ fn zirReify( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, Value.fromInterned(wip_ty.index), name_strategy, "opaque", inst, + extra.src_line, ); mod.declPtr(new_decl_index).owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -21699,7 +21643,7 @@ fn zirReify( .needed_comptime_reason = "union fields must be comptime-known", }); - return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy); + return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy, extra.src_line); }, .Fn => { const struct_type = ip.loadStructType(ip.typeOf(union_val.val)); @@ -21801,6 +21745,7 @@ fn reifyEnum( is_exhaustive: bool, fields_val: Value, name_strategy: Zir.Inst.NameStrategy, + src_line: u32, ) CompileError!Air.Inst.Ref { const mod = sema.mod; const gpa = sema.gpa; @@ -21858,11 +21803,11 @@ fn reifyEnum( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, Value.fromInterned(wip_ty.index), name_strategy, "enum", inst, + src_line, ); mod.declPtr(new_decl_index).owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -21892,17 +21837,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; }, }); @@ -21926,6 +21871,7 @@ fn reifyUnion( opt_tag_type_val: Value, fields_val: Value, name_strategy: Zir.Inst.NameStrategy, + src_line: u32, ) CompileError!Air.Inst.Ref { const mod = sema.mod; const gpa = sema.gpa; @@ -22005,11 +21951,11 @@ fn reifyUnion( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, Value.fromInterned(wip_ty.index), name_strategy, "union", inst, + src_line, ); mod.declPtr(new_decl_index).owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -22061,7 +22007,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| { @@ -22105,7 +22051,7 @@ fn reifyUnion( } } - const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index)); + const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index), src_line); break :tag_ty .{ enum_tag_ty, false }; }; errdefer if (!has_explicit_tag) ip.remove(enum_tag_ty); // remove generated tag type on error @@ -22114,7 +22060,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); @@ -22123,22 +22069,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; @@ -22168,6 +22112,7 @@ fn reifyStruct( fields_val: Value, name_strategy: Zir.Inst.NameStrategy, is_tuple: bool, + src_line: u32, ) CompileError!Air.Inst.Ref { const mod = sema.mod; const gpa = sema.gpa; @@ -22264,11 +22209,11 @@ fn reifyStruct( const new_decl_index = try sema.createAnonymousDeclTypeNamed( block, - src, Value.fromInterned(wip_ty.index), name_strategy, "struct", inst, + src_line, ); mod.declPtr(new_decl_index).owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -22355,7 +22300,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); @@ -22364,7 +22309,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); @@ -22373,22 +22318,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; @@ -22403,7 +22346,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, @@ -22434,22 +22377,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; @@ -22463,8 +22404,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"); @@ -22475,8 +22416,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); @@ -22485,7 +22426,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); @@ -22500,7 +22441,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); @@ -22509,22 +22450,22 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai fn zirFrameType(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 = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); return sema.failWithUseOfAsync(block, src); } fn zirFrameSize(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 = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); return sema.failWithUseOfAsync(block, src); } fn zirIntFromFloat(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 = inst_data.src(); + 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); @@ -22547,7 +22488,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro }); } - try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); + try sema.requireRuntimeBlock(block, src, operand_src); if (dest_scalar_ty.intInfo(mod).bits == 0) { if (!is_vector) { if (block.wantSafety()) { @@ -22604,9 +22545,9 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro fn zirFloatFromInt(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 = inst_data.src(); + 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); @@ -22646,11 +22587,11 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro fn zirPtrFromInt(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 = inst_data.src(); + 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 operand_res = try sema.resolveInst(extra.rhs); const uncoerced_operand_ty = sema.typeOf(operand_res); @@ -22673,9 +22614,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); @@ -22700,11 +22641,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; }); } @@ -22789,8 +22729,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); @@ -22810,12 +22750,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; @@ -22914,8 +22854,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( @@ -22931,8 +22871,8 @@ 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -23002,7 +22942,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), }); @@ -23011,9 +22951,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; }); @@ -23038,13 +22978,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; }); } @@ -23066,41 +23006,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; }); } @@ -23112,12 +23052,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; }); } @@ -23138,15 +23078,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; }); } @@ -23155,15 +23095,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; }); } @@ -23171,9 +23111,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), }); @@ -23185,9 +23125,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; }); } @@ -23196,9 +23136,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; }); } @@ -23347,8 +23287,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); @@ -23378,8 +23318,8 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst fn zirTruncate(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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -23417,16 +23357,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; @@ -23468,8 +23407,8 @@ fn zirBitCount( ) CompileError!Air.Inst.Ref { const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -23522,8 +23461,8 @@ fn zirBitCount( fn zirByteSwap(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 src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -23578,8 +23517,8 @@ 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 = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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); @@ -23637,9 +23576,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); @@ -23752,14 +23691,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; }; @@ -23784,14 +23722,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; }; @@ -24045,26 +23982,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; }; @@ -24072,12 +24009,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, @@ -24091,10 +24022,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, .{ @@ -24191,14 +24122,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); @@ -24287,8 +24218,8 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I 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 src = inst_data.src(); - const scalar_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const src = block.nodeOffset(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)}); @@ -24309,15 +24240,15 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I return Air.internedToRef((try sema.splat(dest_ty, scalar_val)).toIntern()); } - try sema.requireRuntimeBlock(block, inst_data.src(), scalar_src); + try sema.requireRuntimeBlock(block, src, scalar_src); return block.addTyOp(.splat, dest_ty, scalar); } 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", }); @@ -24374,7 +24305,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. return Air.internedToRef(accum.toIntern()); } - try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); + try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), operand_src); return block.addInst(.{ .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce, .data = .{ .reduce = .{ @@ -24388,8 +24319,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); @@ -24424,9 +24355,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; @@ -24490,16 +24421,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; @@ -24577,11 +24508,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); @@ -24668,9 +24599,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); @@ -24701,7 +24632,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! } } - try sema.requireRuntimeBlock(block, inst_data.src(), ptr_src); + try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), ptr_src); return block.addInst(.{ .tag = .atomic_load, .data = .{ .atomic_load = .{ @@ -24715,13 +24646,13 @@ fn zirAtomicRmw(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 extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; - const src = inst_data.src(); + 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); @@ -24800,12 +24731,12 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A fn zirAtomicStore(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.AtomicStore, inst_data.payload_index).data; - const src = inst_data.src(); + 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); @@ -24836,11 +24767,11 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError fn zirMulAdd(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.MulAdd, inst_data.payload_index).data; - const src = inst_data.src(); + 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); @@ -24903,10 +24834,10 @@ 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 call_src = inst_data.src(); + 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; const func = try sema.resolveInst(extra.callee); @@ -25000,9 +24931,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?; const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small))); assert(!flags.ptr_cast); - const inst_src = extra.src(); - 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 inst_src = block.nodeOffset(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); @@ -25191,9 +25122,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; }); } @@ -25210,9 +25141,9 @@ fn zirMinMax( ) 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 src = inst_data.src(); - 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 src = block.nodeOffset(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)); @@ -25228,22 +25159,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.*)); } @@ -25511,9 +25434,9 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A 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 = inst_data.src(); - 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 src = block.nodeOffset(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); @@ -25529,12 +25452,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; @@ -25551,12 +25474,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; @@ -25664,7 +25587,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); @@ -25731,9 +25654,9 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void 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 = inst_data.src(); - 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 src = block.nodeOffset(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); @@ -25755,9 +25678,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; @@ -25810,13 +25733,13 @@ 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); } fn zirResume(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 = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); return sema.failWithUseOfAsync(block, src); } @@ -25826,7 +25749,7 @@ fn zirAwait( inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node; - const src = inst_data.src(); + const src = block.nodeOffset(inst_data.src_node); return sema.failWithUseOfAsync(block, src); } @@ -25837,7 +25760,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); } @@ -25849,8 +25772,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; @@ -25915,11 +25838,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; @@ -26146,7 +26069,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", @@ -26161,7 +26084,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", @@ -26177,8 +26100,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", @@ -26201,8 +26124,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)}); @@ -26227,9 +26150,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)}); @@ -26262,9 +26185,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, .{ @@ -26294,18 +26217,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(.{ @@ -26340,10 +26257,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, .{ @@ -26401,8 +26318,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)) { @@ -26410,29 +26327,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( @@ -26482,8 +26392,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) { @@ -26524,11 +26434,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); @@ -26551,10 +26461,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); @@ -26573,13 +26482,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; @@ -26592,7 +26500,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{}; @@ -26605,7 +26513,7 @@ fn explainWhyTypeIsComptime( fn explainWhyTypeIsComptimeInner( sema: *Sema, msg: *Module.ErrorMsg, - src_loc: Module.SrcLoc, + src_loc: LazySrcLoc, ty: Type, type_set: *TypeSet, ) CompileError!void { @@ -26623,13 +26531,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, @@ -26641,7 +26549,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 => { @@ -26652,14 +26560,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; } @@ -26679,14 +26587,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); } } } @@ -26699,14 +26607,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); } } } @@ -26796,7 +26704,7 @@ fn validateExternType( fn explainWhyTypeIsNotExtern( sema: *Sema, msg: *Module.ErrorMsg, - src_loc: Module.SrcLoc, + src_loc: LazySrcLoc, ty: Type, position: ExternPosition, ) CompileError!void { @@ -26821,55 +26729,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", .{}), } } @@ -26912,7 +26820,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; @@ -26938,19 +26846,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", .{}), } } @@ -27001,11 +26909,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, }).?; @@ -27027,11 +26935,12 @@ fn addSafetyCheck( var fail_block: Block = .{ .parent = parent_block, .sema = sema, - .src_decl = parent_block.src_decl, .namespace = parent_block.namespace, .instructions = .{}, .inlining = parent_block.inlining, .is_comptime = false, + .src_base_inst = parent_block.src_base_inst, + .type_name_ctx = parent_block.type_name_ctx, }; defer fail_block.instructions.deinit(gpa); @@ -27135,11 +27044,12 @@ fn panicUnwrapError( var fail_block: Block = .{ .parent = parent_block, .sema = sema, - .src_decl = parent_block.src_decl, .namespace = parent_block.namespace, .instructions = .{}, .inlining = parent_block.inlining, .is_comptime = false, + .src_base_inst = parent_block.src_base_inst, + .type_name_ctx = parent_block.type_name_ctx, }; defer fail_block.instructions.deinit(gpa); @@ -27251,11 +27161,12 @@ fn safetyCheckFormatted( var fail_block: Block = .{ .parent = parent_block, .sema = sema, - .src_decl = parent_block.src_decl, .namespace = parent_block.namespace, .instructions = .{}, .inlining = parent_block.inlining, .is_comptime = false, + .src_base_inst = parent_block.src_base_inst, + .type_name_ctx = parent_block.type_name_ctx, }; defer fail_block.instructions.deinit(gpa); @@ -27279,13 +27190,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}", @@ -27451,10 +27360,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); @@ -27612,7 +27521,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) @@ -27805,7 +27714,7 @@ fn fieldCallBind( const decl_idx = (try sema.namespaceLookup(block, src, namespace, field_name)) orelse break :found_decl null; - try sema.addReferencedBy(block, src, decl_idx); + try sema.addReferencedBy(src, decl_idx); const decl_val = try sema.analyzeDeclVal(block, src, decl_idx); const decl_type = sema.typeOf(decl_val); if (mod.typeToFunc(decl_type)) |func_type| f: { @@ -27864,7 +27773,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), }); @@ -27872,10 +27781,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; }; @@ -27933,11 +27845,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); @@ -27955,7 +27870,7 @@ fn namespaceLookupRef( decl_name: InternPool.NullTerminatedString, ) CompileError!?Air.Inst.Ref { const decl = (try sema.namespaceLookup(block, src, opt_namespace, decl_name)) orelse return null; - try sema.addReferencedBy(block, src, decl); + try sema.addReferencedBy(src, decl); return try sema.analyzeDeclRef(decl); } @@ -28002,7 +27917,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); } @@ -28117,7 +28032,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]); @@ -28270,7 +28185,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", .{ @@ -28303,7 +28218,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), }); @@ -28371,7 +28286,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); @@ -28594,15 +28509,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; }; @@ -28990,21 +28903,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( @@ -29097,7 +29007,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); @@ -29345,9 +29255,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); @@ -29434,7 +29344,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()); }, @@ -29493,7 +29403,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 '{}'", .{ @@ -29627,54 +29537,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 @@ -29809,7 +29723,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.*) { @@ -29820,93 +29734,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; @@ -29923,69 +29837,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; }, @@ -29993,11 +29907,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), }); } @@ -30005,34 +29919,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; }, }; @@ -30646,7 +30560,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); }, @@ -30694,11 +30608,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; @@ -30858,7 +30771,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; @@ -30892,8 +30804,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 => { @@ -30916,10 +30827,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 @@ -30929,10 +30839,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; }); } @@ -31194,11 +31103,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; }; @@ -31218,7 +31127,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]; @@ -31233,7 +31142,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), }); @@ -31255,7 +31164,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); @@ -31273,7 +31182,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) }, @@ -31297,7 +31205,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) }, @@ -31356,12 +31263,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", .{}, @@ -31438,12 +31343,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); @@ -31525,12 +31430,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); @@ -31701,9 +31606,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; } @@ -31839,18 +31744,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; } @@ -31884,7 +31789,7 @@ fn analyzeDeclVal( src: LazySrcLoc, decl_index: InternPool.DeclIndex, ) CompileError!Air.Inst.Ref { - try sema.addReferencedBy(block, src, decl_index); + try sema.addReferencedBy(src, decl_index); if (sema.decl_val_table.get(decl_index)) |result| { return result; } @@ -31900,21 +31805,14 @@ fn analyzeDeclVal( fn addReferencedBy( sema: *Sema, - block: *Block, src: LazySrcLoc, 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, + // TODO: this can make the reference trace suboptimal. This will be fixed + // once the reference table is reworked for incremental compilation. + .referencer = sema.owner_decl_index, .src = src, }); } @@ -31924,7 +31822,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); } @@ -32419,10 +32320,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 '{}'", @@ -32436,10 +32336,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 '{}'", @@ -32693,9 +32592,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), }); @@ -33567,6 +33466,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, @@ -33591,10 +33515,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); @@ -33622,9 +33545,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 @@ -33646,8 +33569,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 '{}'"; @@ -33656,16 +33579,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; @@ -33680,7 +33603,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, @@ -35119,9 +35042,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; @@ -35129,16 +35052,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); } @@ -35175,9 +35097,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", .{}, ); @@ -35185,11 +35106,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", .{}, ); @@ -35221,7 +35141,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! @@ -35272,7 +35192,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 = .{ @@ -35294,11 +35214,12 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co var block: Block = .{ .parent = null, .sema = &sema, - .src_decl = decl_index, .namespace = struct_type.namespace.unwrap() orelse decl.src_namespace, .instructions = .{}, .inlining = null, .is_comptime = true, + .src_base_inst = struct_type.zir_index.unwrap().?, + .type_name_ctx = decl.name, }; defer assert(block.instructions.items.len == 0); @@ -35331,7 +35252,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]); @@ -35347,7 +35271,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(); @@ -35374,9 +35298,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); @@ -35397,9 +35321,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); @@ -35450,8 +35374,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)); @@ -35461,11 +35385,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); }, @@ -35484,7 +35407,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 => { @@ -35526,7 +35449,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); @@ -35545,9 +35468,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", .{}, ); @@ -35555,11 +35477,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", .{}, ); @@ -35783,12 +35704,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, @@ -35802,20 +35723,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; }, @@ -35824,9 +35744,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 @@ -35835,20 +35755,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; }, @@ -35858,9 +35777,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, @@ -35874,11 +35793,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); }, @@ -35892,7 +35810,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; @@ -35942,10 +35860,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); @@ -36126,7 +36047,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 = .{ @@ -36148,11 +36069,12 @@ fn semaStructFields( var block_scope: Block = .{ .parent = null, .sema = &sema, - .src_decl = decl_index, .namespace = namespace_index, .instructions = .{}, .inlining = null, .is_comptime = true, + .src_base_inst = struct_type.zir_index.unwrap().?, + .type_name_ctx = decl.name, }; defer assert(block_scope.instructions.items.len == 0); @@ -36231,35 +36153,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; @@ -36269,11 +36175,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); @@ -36283,11 +36185,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); @@ -36298,11 +36196,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); @@ -36314,11 +36208,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); @@ -36335,17 +36225,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; } @@ -36374,7 +36258,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 = .{ @@ -36396,11 +36280,12 @@ fn semaStructFieldInits( var block_scope: Block = .{ .parent = null, .sema = &sema, - .src_decl = decl_index, .namespace = namespace_index, .instructions = .{}, .inlining = null, .is_comptime = true, + .src_base_inst = struct_type.zir_index.unwrap().?, + .type_name_ctx = decl.name, }; defer assert(block_scope.instructions.items.len == 0); @@ -36474,33 +36359,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(); @@ -36520,9 +36392,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended; assert(extended.opcode == .union_decl); 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 extra = zir.extraData(Zir.Inst.UnionDecl, extended.operand); + var extra_index: usize = extra.end; const tag_type_ref: Zir.Inst.Ref = if (small.has_tag_type) blk: { const ty_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]); @@ -36562,7 +36433,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 = .{ @@ -36584,14 +36455,17 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded var block_scope: Block = .{ .parent = null, .sema = &sema, - .src_decl = decl_index, .namespace = union_type.namespace.unwrap().?, .instructions = .{}, .inlining = null, .is_comptime = true, + .src_base_inst = union_type.zir_index, + .type_name_ctx = decl.name, }; 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); } @@ -36601,7 +36475,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. @@ -36614,9 +36491,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, }); @@ -36701,19 +36578,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; @@ -36728,12 +36612,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); @@ -36751,17 +36637,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; @@ -36770,11 +36646,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), }); }; @@ -36787,17 +36659,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); @@ -36806,11 +36676,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); @@ -36823,14 +36689,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; @@ -36838,14 +36700,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; @@ -36857,17 +36715,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 { @@ -36882,7 +36730,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| { @@ -36897,10 +36745,10 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded return sema.failWithOwnedErrorMsg(&block_scope, msg); } } else if (enum_field_vals.count() > 0) { - const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), mod.declPtr(union_type.decl)); + const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), mod.declPtr(union_type.decl), extra.data.src_line); union_type.tagTypePtr(ip).* = enum_ty; } else { - const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, mod.declPtr(union_type.decl)); + const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, mod.declPtr(union_type.decl), extra.data.src_line); union_type.tagTypePtr(ip).* = enum_ty; } } @@ -36918,13 +36766,13 @@ fn generateUnionTagTypeNumbered( enum_field_names: []const InternPool.NullTerminatedString, enum_field_vals: []const InternPool.Index, union_owner_decl: *Module.Decl, + src_line: u32, ) !InternPool.Index { const mod = sema.mod; const gpa = sema.gpa; 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( @@ -36935,7 +36783,7 @@ fn generateUnionTagTypeNumbered( ); try mod.initNewAnonDecl( new_decl_index, - src_decl.src_line, + src_line, Value.@"unreachable", name, ); @@ -36968,6 +36816,7 @@ fn generateUnionTagTypeSimple( block: *Block, enum_field_names: []const InternPool.NullTerminatedString, union_owner_decl: *Module.Decl, + src_line: u32, ) !InternPool.Index { const mod = sema.mod; const ip = &mod.intern_pool; @@ -36975,8 +36824,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, @@ -36986,7 +36834,7 @@ fn generateUnionTagTypeSimple( ); try mod.initNewAnonDecl( new_decl_index, - src_decl.src_line, + src_line, Value.@"unreachable", name, ); @@ -37016,19 +36864,33 @@ 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, .sema = sema, - .src_decl = sema.owner_decl_index, .namespace = sema.owner_decl.src_namespace, .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, + } + }, + .type_name_ctx = sema.owner_decl.name, }; - 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); @@ -37037,7 +36899,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; @@ -37064,19 +36926,34 @@ 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 = .{ .parent = null, .sema = sema, - .src_decl = sema.owner_decl_index, .namespace = sema.owner_decl.src_namespace, .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, + } + }, + .type_name_ctx = sema.owner_decl.name, }; 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}), @@ -37092,12 +36969,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, @@ -37160,7 +37037,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 @@ -37274,13 +37151,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() }, } }))); @@ -37295,7 +37172,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 = &.{} }, } }))); @@ -37312,12 +37189,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); @@ -37329,7 +37205,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 }, } }))); @@ -37342,7 +37218,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)) }, } }))); @@ -37354,23 +37230,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(), @@ -37385,7 +37260,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(), } }); @@ -37395,18 +37270,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, ), } }), @@ -37744,7 +37619,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); } @@ -37763,7 +37638,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); } } @@ -38535,9 +38410,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; }); } @@ -38628,6 +38503,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; |
