@@ -349,6 +349,16 @@ pub const Block = struct {
349349 /// if we need to add type coercion at the end of block analysis.
350350 /// Same indexes, capacity, length as `results`.
351351 br_list: std.ArrayListUnmanaged(Air.Inst.Index),
352+ /// Keeps the source location of the rhs operand of the break instruction,
353+ /// to enable more precise compile errors.
354+ /// Same indexes, capacity, length as `results`.
355+ src_locs: std.ArrayListUnmanaged(?LazySrcLoc),
356+
357+ pub fn deinit(merges: *@This(), allocator: mem.Allocator) void {
358+ merges.results.deinit(allocator);
359+ merges.br_list.deinit(allocator);
360+ merges.src_locs.deinit(allocator);
361+ }
352362 };
353363
354364 /// For debugging purposes.
@@ -722,8 +732,7 @@ const LabeledBlock = struct {
722732
723733 fn destroy(lb: *LabeledBlock, gpa: Allocator) void {
724734 lb.block.instructions.deinit(gpa);
725- lb.label.merges.results.deinit(gpa);
726- lb.label.merges.br_list.deinit(gpa);
735+ lb.label.merges.deinit(gpa);
727736 gpa.destroy(lb);
728737 }
729738};
@@ -777,8 +786,9 @@ fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.In
777786 error.ComptimeBreak => {
778787 const zir_datas = sema.code.instructions.items(.data);
779788 const break_data = zir_datas[sema.comptime_break_inst].@"break";
789+ const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
780790 try sema.addRuntimeBreak(block, .{
781- .block_inst = break_data .block_inst,
791+ .block_inst = extra .block_inst,
782792 .operand = break_data.operand,
783793 .inst = sema.comptime_break_inst,
784794 });
@@ -817,8 +827,9 @@ pub fn analyzeBodyBreak(
817827 sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn())
818828 return null;
819829 const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
830+ const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
820831 return BreakData{
821- .block_inst = break_data .block_inst,
832+ .block_inst = extra .block_inst,
822833 .operand = break_data.operand,
823834 .inst = break_inst,
824835 };
@@ -5238,6 +5249,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
52385249 var label: Block.Label = .{
52395250 .zir_block = inst,
52405251 .merges = .{
5252+ .src_locs = .{},
52415253 .results = .{},
52425254 .br_list = .{},
52435255 .block_inst = block_inst,
@@ -5251,8 +5263,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
52515263 const merges = &child_block.label.?.merges;
52525264
52535265 defer child_block.instructions.deinit(gpa);
5254- defer merges.results.deinit(gpa);
5255- defer merges.br_list.deinit(gpa);
5266+ defer merges.deinit(gpa);
52565267
52575268 var loop_block = child_block.makeSubBlock();
52585269 defer loop_block.instructions.deinit(gpa);
@@ -5422,6 +5433,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
54225433 var label: Block.Label = .{
54235434 .zir_block = inst,
54245435 .merges = .{
5436+ .src_locs = .{},
54255437 .results = .{},
54265438 .br_list = .{},
54275439 .block_inst = block_inst,
@@ -5450,8 +5462,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
54505462 };
54515463
54525464 defer child_block.instructions.deinit(gpa);
5453- defer label.merges.results.deinit(gpa);
5454- defer label.merges.br_list.deinit(gpa);
5465+ defer label.merges.deinit(gpa);
54555466
54565467 return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
54575468}
@@ -5480,7 +5491,8 @@ fn resolveBlockBody(
54805491
54815492 const break_inst = sema.comptime_break_inst;
54825493 const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
5483- if (break_data.block_inst == body_inst) {
5494+ const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
5495+ if (extra.block_inst == body_inst) {
54845496 return try sema.resolveInst(break_data.operand);
54855497 } else {
54865498 return error.ComptimeBreak;
@@ -5533,7 +5545,7 @@ fn analyzeBlockBody(
55335545 // Need to set the type and emit the Block instruction. This allows machine code generation
55345546 // to emit a jump instruction to after the block when it encounters the break.
55355547 try parent_block.instructions.append(gpa, merges.block_inst);
5536- const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .none );
5548+ const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .{ .override = merges.src_locs.items } );
55375549 // TODO add note "missing else causes void value"
55385550
55395551 const type_src = src; // TODO: better source location
@@ -5842,14 +5854,20 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
58425854 defer tracy.end();
58435855
58445856 const inst_data = sema.code.instructions.items(.data)[inst].@"break";
5857+ const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
58455858 const operand = try sema.resolveInst(inst_data.operand);
5846- const zir_block = inst_data .block_inst;
5859+ const zir_block = extra .block_inst;
58475860
58485861 var block = start_block;
58495862 while (true) {
58505863 if (block.label) |label| {
58515864 if (label.zir_block == zir_block) {
58525865 const br_ref = try start_block.addBr(label.merges.block_inst, operand);
5866+ const src_loc = if (extra.operand_src_node != Zir.Inst.Break.no_src_node)
5867+ LazySrcLoc.nodeOffset(extra.operand_src_node)
5868+ else
5869+ null;
5870+ try label.merges.src_locs.append(sema.gpa, src_loc);
58535871 try label.merges.results.append(sema.gpa, operand);
58545872 try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);
58555873 block.runtime_index.increment();
@@ -6643,6 +6661,7 @@ fn analyzeCall(
66436661 .func = null,
66446662 .comptime_result = undefined,
66456663 .merges = .{
6664+ .src_locs = .{},
66466665 .results = .{},
66476666 .br_list = .{},
66486667 .block_inst = block_inst,
@@ -6692,8 +6711,7 @@ fn analyzeCall(
66926711 const merges = &child_block.inlining.?.merges;
66936712
66946713 defer child_block.instructions.deinit(gpa);
6695- defer merges.results.deinit(gpa);
6696- defer merges.br_list.deinit(gpa);
6714+ defer merges.deinit(gpa);
66976715
66986716 // If it's a comptime function call, we need to memoize it as long as no external
66996717 // comptime memory is mutated.
@@ -10780,6 +10798,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1078010798 var label: Block.Label = .{
1078110799 .zir_block = inst,
1078210800 .merges = .{
10801+ .src_locs = .{},
1078310802 .results = .{},
1078410803 .br_list = .{},
1078510804 .block_inst = block_inst,
@@ -10807,8 +10826,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1080710826 };
1080810827 const merges = &child_block.label.?.merges;
1080910828 defer child_block.instructions.deinit(gpa);
10810- defer merges.results.deinit(gpa);
10811- defer merges.br_list.deinit(gpa);
10829+ defer merges.deinit(gpa);
1081210830
1081310831 if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {
1081410832 var extra_index: usize = special.end;
@@ -12298,7 +12316,7 @@ fn zirBitwise(
1229812316 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1229912317
1230012318 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
12301- const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
12319+ const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src } });
1230212320 const scalar_type = resolved_type.scalarType();
1230312321 const scalar_tag = scalar_type.zigTypeTag();
1230412322
@@ -12502,7 +12520,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1250212520 try trash_block.addBitCast(rhs_info.elem_type, .void_value),
1250312521 };
1250412522 break :t try sema.resolvePeerTypes(block, src, &instructions, .{
12505- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
12523+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1250612524 });
1250712525 };
1250812526
@@ -13002,7 +13020,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1300213020
1300313021 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1300413022 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13005- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13023+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1300613024 });
1300713025
1300813026 const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13162,7 +13180,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1316213180
1316313181 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1316413182 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13165- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13183+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1316613184 });
1316713185
1316813186 const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13325,7 +13343,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1332513343
1332613344 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1332713345 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13328- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13346+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1332913347 });
1333013348
1333113349 const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13441,7 +13459,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1344113459
1344213460 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1344313461 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13444- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13462+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1344513463 });
1344613464
1344713465 const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13683,7 +13701,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1368313701
1368413702 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1368513703 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13686- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13704+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1368713705 });
1368813706
1368913707 const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13866,7 +13884,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1386613884
1386713885 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1386813886 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13869- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13887+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1387013888 });
1387113889
1387213890 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
@@ -13968,7 +13986,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1396813986
1396913987 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1397013988 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13971- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13989+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1397213990 });
1397313991
1397413992 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
@@ -14081,7 +14099,7 @@ fn zirOverflowArithmetic(
1408114099 lhs_ty
1408214100 else
1408314101 try sema.resolvePeerTypes(block, src, instructions, .{
14084- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
14102+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1408514103 });
1408614104
1408714105 const rhs_dest_ty = if (zir_tag == .shl_with_overflow)
@@ -14312,7 +14330,7 @@ fn analyzeArithmetic(
1431214330
1431314331 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
1431414332 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
14315- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
14333+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
1431614334 });
1431714335
1431814336 const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -15200,7 +15218,7 @@ fn analyzeCmp(
1520015218 return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
1520115219 }
1520215220 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
15203- const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
15221+ const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src } });
1520415222 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
1520515223 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
1520615224 compareOperatorName(op), resolved_type.fmt(sema.mod),
@@ -17024,6 +17042,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi
1702417042 .label = .{
1702517043 .zir_block = break_data.block_inst,
1702617044 .merges = .{
17045+ .src_locs = .{},
1702717046 .results = .{},
1702817047 .br_list = .{},
1702917048 .block_inst = new_block_inst,
@@ -20605,7 +20624,7 @@ fn checkSimdBinOp(
2060520624 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
2060620625 var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null;
2060720626 const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{
20608- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
20627+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
2060920628 });
2061020629 const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src);
2061120630 const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src);
0 commit comments