@@ -349,6 +349,16 @@ pub const Block = struct {
349
349
/// if we need to add type coercion at the end of block analysis.
350
350
/// Same indexes, capacity, length as `results`.
351
351
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
+ }
352
362
};
353
363
354
364
/// For debugging purposes.
@@ -722,8 +732,7 @@ const LabeledBlock = struct {
722
732
723
733
fn destroy(lb: *LabeledBlock, gpa: Allocator) void {
724
734
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);
727
736
gpa.destroy(lb);
728
737
}
729
738
};
@@ -777,8 +786,9 @@ fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.In
777
786
error.ComptimeBreak => {
778
787
const zir_datas = sema.code.instructions.items(.data);
779
788
const break_data = zir_datas[sema.comptime_break_inst].@"break";
789
+ const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
780
790
try sema.addRuntimeBreak(block, .{
781
- .block_inst = break_data .block_inst,
791
+ .block_inst = extra .block_inst,
782
792
.operand = break_data.operand,
783
793
.inst = sema.comptime_break_inst,
784
794
});
@@ -817,8 +827,9 @@ pub fn analyzeBodyBreak(
817
827
sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn())
818
828
return null;
819
829
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;
820
831
return BreakData{
821
- .block_inst = break_data .block_inst,
832
+ .block_inst = extra .block_inst,
822
833
.operand = break_data.operand,
823
834
.inst = break_inst,
824
835
};
@@ -5238,6 +5249,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5238
5249
var label: Block.Label = .{
5239
5250
.zir_block = inst,
5240
5251
.merges = .{
5252
+ .src_locs = .{},
5241
5253
.results = .{},
5242
5254
.br_list = .{},
5243
5255
.block_inst = block_inst,
@@ -5251,8 +5263,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5251
5263
const merges = &child_block.label.?.merges;
5252
5264
5253
5265
defer child_block.instructions.deinit(gpa);
5254
- defer merges.results.deinit(gpa);
5255
- defer merges.br_list.deinit(gpa);
5266
+ defer merges.deinit(gpa);
5256
5267
5257
5268
var loop_block = child_block.makeSubBlock();
5258
5269
defer loop_block.instructions.deinit(gpa);
@@ -5422,6 +5433,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5422
5433
var label: Block.Label = .{
5423
5434
.zir_block = inst,
5424
5435
.merges = .{
5436
+ .src_locs = .{},
5425
5437
.results = .{},
5426
5438
.br_list = .{},
5427
5439
.block_inst = block_inst,
@@ -5450,8 +5462,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5450
5462
};
5451
5463
5452
5464
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);
5455
5466
5456
5467
return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
5457
5468
}
@@ -5480,7 +5491,8 @@ fn resolveBlockBody(
5480
5491
5481
5492
const break_inst = sema.comptime_break_inst;
5482
5493
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) {
5484
5496
return try sema.resolveInst(break_data.operand);
5485
5497
} else {
5486
5498
return error.ComptimeBreak;
@@ -5533,7 +5545,7 @@ fn analyzeBlockBody(
5533
5545
// Need to set the type and emit the Block instruction. This allows machine code generation
5534
5546
// to emit a jump instruction to after the block when it encounters the break.
5535
5547
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 } );
5537
5549
// TODO add note "missing else causes void value"
5538
5550
5539
5551
const type_src = src; // TODO: better source location
@@ -5842,14 +5854,20 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
5842
5854
defer tracy.end();
5843
5855
5844
5856
const inst_data = sema.code.instructions.items(.data)[inst].@"break";
5857
+ const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
5845
5858
const operand = try sema.resolveInst(inst_data.operand);
5846
- const zir_block = inst_data .block_inst;
5859
+ const zir_block = extra .block_inst;
5847
5860
5848
5861
var block = start_block;
5849
5862
while (true) {
5850
5863
if (block.label) |label| {
5851
5864
if (label.zir_block == zir_block) {
5852
5865
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);
5853
5871
try label.merges.results.append(sema.gpa, operand);
5854
5872
try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);
5855
5873
block.runtime_index.increment();
@@ -6643,6 +6661,7 @@ fn analyzeCall(
6643
6661
.func = null,
6644
6662
.comptime_result = undefined,
6645
6663
.merges = .{
6664
+ .src_locs = .{},
6646
6665
.results = .{},
6647
6666
.br_list = .{},
6648
6667
.block_inst = block_inst,
@@ -6692,8 +6711,7 @@ fn analyzeCall(
6692
6711
const merges = &child_block.inlining.?.merges;
6693
6712
6694
6713
defer child_block.instructions.deinit(gpa);
6695
- defer merges.results.deinit(gpa);
6696
- defer merges.br_list.deinit(gpa);
6714
+ defer merges.deinit(gpa);
6697
6715
6698
6716
// If it's a comptime function call, we need to memoize it as long as no external
6699
6717
// comptime memory is mutated.
@@ -10780,6 +10798,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10780
10798
var label: Block.Label = .{
10781
10799
.zir_block = inst,
10782
10800
.merges = .{
10801
+ .src_locs = .{},
10783
10802
.results = .{},
10784
10803
.br_list = .{},
10785
10804
.block_inst = block_inst,
@@ -10807,8 +10826,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10807
10826
};
10808
10827
const merges = &child_block.label.?.merges;
10809
10828
defer child_block.instructions.deinit(gpa);
10810
- defer merges.results.deinit(gpa);
10811
- defer merges.br_list.deinit(gpa);
10829
+ defer merges.deinit(gpa);
10812
10830
10813
10831
if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {
10814
10832
var extra_index: usize = special.end;
@@ -12298,7 +12316,7 @@ fn zirBitwise(
12298
12316
try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
12299
12317
12300
12318
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 } });
12302
12320
const scalar_type = resolved_type.scalarType();
12303
12321
const scalar_tag = scalar_type.zigTypeTag();
12304
12322
@@ -12502,7 +12520,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12502
12520
try trash_block.addBitCast(rhs_info.elem_type, .void_value),
12503
12521
};
12504
12522
break :t try sema.resolvePeerTypes(block, src, &instructions, .{
12505
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
12523
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
12506
12524
});
12507
12525
};
12508
12526
@@ -13002,7 +13020,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13002
13020
13003
13021
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13004
13022
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13005
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13023
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
13006
13024
});
13007
13025
13008
13026
const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13162,7 +13180,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13162
13180
13163
13181
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13164
13182
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13165
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13183
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
13166
13184
});
13167
13185
13168
13186
const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13325,7 +13343,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13325
13343
13326
13344
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13327
13345
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13328
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13346
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
13329
13347
});
13330
13348
13331
13349
const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13441,7 +13459,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13441
13459
13442
13460
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13443
13461
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13444
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13462
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
13445
13463
});
13446
13464
13447
13465
const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13683,7 +13701,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13683
13701
13684
13702
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13685
13703
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13686
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13704
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
13687
13705
});
13688
13706
13689
13707
const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -13866,7 +13884,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
13866
13884
13867
13885
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13868
13886
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13869
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13887
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
13870
13888
});
13871
13889
13872
13890
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
13968
13986
13969
13987
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13970
13988
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
13971
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
13989
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
13972
13990
});
13973
13991
13974
13992
const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
@@ -14081,7 +14099,7 @@ fn zirOverflowArithmetic(
14081
14099
lhs_ty
14082
14100
else
14083
14101
try sema.resolvePeerTypes(block, src, instructions, .{
14084
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
14102
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
14085
14103
});
14086
14104
14087
14105
const rhs_dest_ty = if (zir_tag == .shl_with_overflow)
@@ -14312,7 +14330,7 @@ fn analyzeArithmetic(
14312
14330
14313
14331
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
14314
14332
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{
14315
- .override = &[_]LazySrcLoc{ lhs_src, rhs_src },
14333
+ .override = &[_]? LazySrcLoc{ lhs_src, rhs_src },
14316
14334
});
14317
14335
14318
14336
const is_vector = resolved_type.zigTypeTag() == .Vector;
@@ -15200,7 +15218,7 @@ fn analyzeCmp(
15200
15218
return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
15201
15219
}
15202
15220
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 } });
15204
15222
if (!resolved_type.isSelfComparable(is_equality_cmp)) {
15205
15223
return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
15206
15224
compareOperatorName(op), resolved_type.fmt(sema.mod),
@@ -17024,6 +17042,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi
17024
17042
.label = .{
17025
17043
.zir_block = break_data.block_inst,
17026
17044
.merges = .{
17045
+ .src_locs = .{},
17027
17046
.results = .{},
17028
17047
.br_list = .{},
17029
17048
.block_inst = new_block_inst,
@@ -20605,7 +20624,7 @@ fn checkSimdBinOp(
20605
20624
try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
20606
20625
var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null;
20607
20626
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 },
20609
20628
});
20610
20629
const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src);
20611
20630
const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src);
0 commit comments