authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2023-02-25 20:44:53+01:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-03-21 15:09:42+02:00
logec445fb6b8bb3f3d423cafa4f3a7860da65ca233
treed9e9a35edb8bd62431fa5a0e9f0945ad62e10a48
parent8642770eff4f1770aa5de88907946c60fe5ff0d8

Improve error messages for break type coercion


9 files changed, 199 insertions(+), 67 deletions(-)

src/AstGen.zig+133-36
...@@ -1280,7 +1280,7 @@ fn fnProtoExpr(...@@ -1280,7 +1280,7 @@ fn fnProtoExpr(
1280 defer param_gz.unstack();1280 defer param_gz.unstack();
1281 const param_type = try expr(&param_gz, scope, coerced_type_ri, param_type_node);1281 const param_type = try expr(&param_gz, scope, coerced_type_ri, param_type_node);
1282 const param_inst_expected = @intCast(u32, astgen.instructions.len + 1);1282 const param_inst_expected = @intCast(u32, astgen.instructions.len + 1);
1283 _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type);1283 _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node);
1284 const main_tokens = tree.nodes.items(.main_token);1284 const main_tokens = tree.nodes.items(.main_token);
1285 const name_token = param.name_token orelse main_tokens[param_type_node];1285 const name_token = param.name_token orelse main_tokens[param_type_node];
1286 const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param;1286 const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param;
...@@ -1991,7 +1991,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn...@@ -1991,7 +1991,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
19911991
1992 switch (block_gz.break_result_info.rl) {1992 switch (block_gz.break_result_info.rl) {
1993 .block_ptr => {1993 .block_ptr => {
1994 const br = try parent_gz.addBreak(break_tag, block_inst, operand);1994 const br = try parent_gz.addBreakWithSrcNode(break_tag, block_inst, operand, rhs);
1995 try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index });1995 try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index });
1996 },1996 },
1997 .ptr => {1997 .ptr => {
...@@ -2003,7 +2003,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn...@@ -2003,7 +2003,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
2003 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);2003 _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
2004 },2004 },
2005 else => {2005 else => {
2006 _ = try parent_gz.addBreak(break_tag, block_inst, operand);2006 _ = try parent_gz.addBreakWithSrcNode(break_tag, block_inst, operand, rhs);
2007 },2007 },
2008 }2008 }
2009 return Zir.Inst.Ref.unreachable_value;2009 return Zir.Inst.Ref.unreachable_value;
...@@ -3754,7 +3754,7 @@ fn fnDecl(...@@ -3754,7 +3754,7 @@ fn fnDecl(
3754 defer param_gz.unstack();3754 defer param_gz.unstack();
3755 const param_type = try expr(&param_gz, params_scope, coerced_type_ri, param_type_node);3755 const param_type = try expr(&param_gz, params_scope, coerced_type_ri, param_type_node);
3756 const param_inst_expected = @intCast(u32, astgen.instructions.len + 1);3756 const param_inst_expected = @intCast(u32, astgen.instructions.len + 1);
3757 _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type);3757 _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node);
37583758
3759 const main_tokens = tree.nodes.items(.main_token);3759 const main_tokens = tree.nodes.items(.main_token);
3760 const name_token = param.name_token orelse main_tokens[param_type_node];3760 const name_token = param.name_token orelse main_tokens[param_type_node];
...@@ -4114,7 +4114,7 @@ fn globalVarDecl(...@@ -4114,7 +4114,7 @@ fn globalVarDecl(
4114 };4114 };
4115 // We do this at the end so that the instruction index marks the end4115 // We do this at the end so that the instruction index marks the end
4116 // range of a top level declaration.4116 // range of a top level declaration.
4117 _ = try block_scope.addBreak(.break_inline, block_inst, var_inst);4117 _ = try block_scope.addBreakWithSrcNode(.break_inline, block_inst, var_inst, node);
4118 try block_scope.setBlockBody(block_inst);4118 try block_scope.setBlockBody(block_inst);
41194119
4120 {4120 {
...@@ -5456,7 +5456,9 @@ fn orelseCatchExpr(...@@ -5456,7 +5456,9 @@ fn orelseCatchExpr(
5456 condbr,5456 condbr,
5457 cond,5457 cond,
5458 then_result,5458 then_result,
5459 node,
5459 else_result,5460 else_result,
5461 rhs,
5460 block,5462 block,
5461 block,5463 block,
5462 break_tag,5464 break_tag,
...@@ -5475,7 +5477,9 @@ fn finishThenElseBlock(...@@ -5475,7 +5477,9 @@ fn finishThenElseBlock(
5475 condbr: Zir.Inst.Index,5477 condbr: Zir.Inst.Index,
5476 cond: Zir.Inst.Ref,5478 cond: Zir.Inst.Ref,
5477 then_result: Zir.Inst.Ref,5479 then_result: Zir.Inst.Ref,
5480 then_src_node: Ast.Node.Index,
5478 else_result: Zir.Inst.Ref,5481 else_result: Zir.Inst.Ref,
5482 else_src_node: Ast.Node.Index,
5479 main_block: Zir.Inst.Index,5483 main_block: Zir.Inst.Index,
5480 then_break_block: Zir.Inst.Index,5484 then_break_block: Zir.Inst.Index,
5481 break_tag: Zir.Inst.Tag,5485 break_tag: Zir.Inst.Tag,
...@@ -5498,11 +5502,11 @@ fn finishThenElseBlock(...@@ -5498,11 +5502,11 @@ fn finishThenElseBlock(
5498 return indexToRef(main_block);5502 return indexToRef(main_block);
5499 },5503 },
5500 .break_operand => {5504 .break_operand => {
5501 const then_break = if (!then_no_return) try then_scope.makeBreak(break_tag, then_break_block, then_result) else 0;5505 const then_break = if (!then_no_return) try then_scope.makeBreakWithSrcNode(break_tag, then_break_block, then_result, then_src_node) else 0;
5502 const else_break = if (else_result == .none)5506 const else_break = if (else_result == .none)
5503 try else_scope.makeBreak(break_tag, main_block, .void_value)5507 try else_scope.makeBreak(break_tag, main_block, .void_value)
5504 else if (!else_no_return)5508 else if (!else_no_return)
5505 try else_scope.makeBreak(break_tag, main_block, else_result)5509 try else_scope.makeBreakWithSrcNode(break_tag, main_block, else_result, else_src_node)
5506 else5510 else
5507 0;5511 0;
55085512
...@@ -5683,7 +5687,7 @@ fn boolBinOp(...@@ -5683,7 +5687,7 @@ fn boolBinOp(
5683 defer rhs_scope.unstack();5687 defer rhs_scope.unstack();
5684 const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_ri, node_datas[node].rhs);5688 const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_ri, node_datas[node].rhs);
5685 if (!gz.refIsNoReturn(rhs)) {5689 if (!gz.refIsNoReturn(rhs)) {
5686 _ = try rhs_scope.addBreak(.break_inline, bool_br, rhs);5690 _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs);
5687 }5691 }
5688 try rhs_scope.setBoolBrBody(bool_br);5692 try rhs_scope.setBoolBrBody(bool_br);
56895693
...@@ -5758,6 +5762,7 @@ fn ifExpr(...@@ -5758,6 +5762,7 @@ fn ifExpr(
5758 var payload_val_scope: Scope.LocalVal = undefined;5762 var payload_val_scope: Scope.LocalVal = undefined;
57595763
5760 try then_scope.addDbgBlockBegin();5764 try then_scope.addDbgBlockBegin();
5765 const then_node = if_full.ast.then_expr;
5761 const then_sub_scope = s: {5766 const then_sub_scope = s: {
5762 if (if_full.error_token != null) {5767 if (if_full.error_token != null) {
5763 if (if_full.payload_token) |payload_token| {5768 if (if_full.payload_token) |payload_token| {
...@@ -5765,7 +5770,7 @@ fn ifExpr(...@@ -5765,7 +5770,7 @@ fn ifExpr(
5765 .err_union_payload_unsafe_ptr5770 .err_union_payload_unsafe_ptr
5766 else5771 else
5767 .err_union_payload_unsafe;5772 .err_union_payload_unsafe;
5768 const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr);5773 const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node);
5769 const token_name_index = payload_token + @boolToInt(payload_is_ref);5774 const token_name_index = payload_token + @boolToInt(payload_is_ref);
5770 const ident_name = try astgen.identAsString(token_name_index);5775 const ident_name = try astgen.identAsString(token_name_index);
5771 const token_name_str = tree.tokenSlice(token_name_index);5776 const token_name_str = tree.tokenSlice(token_name_index);
...@@ -5795,7 +5800,7 @@ fn ifExpr(...@@ -5795,7 +5800,7 @@ fn ifExpr(
5795 const ident_bytes = tree.tokenSlice(ident_token);5800 const ident_bytes = tree.tokenSlice(ident_token);
5796 if (mem.eql(u8, "_", ident_bytes))5801 if (mem.eql(u8, "_", ident_bytes))
5797 break :s &then_scope.base;5802 break :s &then_scope.base;
5798 const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr);5803 const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node);
5799 const ident_name = try astgen.identAsString(ident_token);5804 const ident_name = try astgen.identAsString(ident_token);
5800 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);5805 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
5801 payload_val_scope = .{5806 payload_val_scope = .{
...@@ -5813,7 +5818,7 @@ fn ifExpr(...@@ -5813,7 +5818,7 @@ fn ifExpr(
5813 }5818 }
5814 };5819 };
58155820
5816 const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, if_full.ast.then_expr);5821 const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node);
5817 if (!then_scope.endsWithNoReturn()) {5822 if (!then_scope.endsWithNoReturn()) {
5818 block_scope.break_count += 1;5823 block_scope.break_count += 1;
5819 }5824 }
...@@ -5878,7 +5883,7 @@ fn ifExpr(...@@ -5878,7 +5883,7 @@ fn ifExpr(
5878 .result = e,5883 .result = e,
5879 };5884 };
5880 } else .{5885 } else .{
5881 .src = if_full.ast.then_expr,5886 .src = then_node,
5882 .result = switch (ri.rl) {5887 .result = switch (ri.rl) {
5883 // Explicitly store void to ptr result loc if there is no else branch5888 // Explicitly store void to ptr result loc if there is no else branch
5884 .ptr, .block_ptr => try rvalue(&else_scope, ri, .void_value, node),5889 .ptr, .block_ptr => try rvalue(&else_scope, ri, .void_value, node),
...@@ -5897,7 +5902,9 @@ fn ifExpr(...@@ -5897,7 +5902,9 @@ fn ifExpr(
5897 condbr,5902 condbr,
5898 cond.bool_bit,5903 cond.bool_bit,
5899 then_result,5904 then_result,
5905 then_node,
5900 else_info.result,5906 else_info.result,
5907 else_info.src,
5901 block,5908 block,
5902 block,5909 block,
5903 break_tag,5910 break_tag,
...@@ -6185,6 +6192,7 @@ fn whileExpr(...@@ -6185,6 +6192,7 @@ fn whileExpr(
6185 then_scope.instructions_top = then_scope.instructions.items.len;6192 then_scope.instructions_top = then_scope.instructions.items.len;
61866193
6187 try then_scope.addDbgBlockBegin();6194 try then_scope.addDbgBlockBegin();
6195 const then_node = while_full.ast.then_expr;
6188 if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst);6196 if (payload_inst != 0) try then_scope.instructions.append(astgen.gpa, payload_inst);
6189 if (dbg_var_name) |name| try then_scope.addDbgVar(.dbg_var_val, name, dbg_var_inst);6197 if (dbg_var_name) |name| try then_scope.addDbgVar(.dbg_var_val, name, dbg_var_inst);
6190 try then_scope.instructions.append(astgen.gpa, continue_block);6198 try then_scope.instructions.append(astgen.gpa, continue_block);
...@@ -6198,7 +6206,7 @@ fn whileExpr(...@@ -6198,7 +6206,7 @@ fn whileExpr(
6198 try then_scope.addDbgBlockEnd();6206 try then_scope.addDbgBlockEnd();
61996207
6200 continue_scope.instructions_top = continue_scope.instructions.items.len;6208 continue_scope.instructions_top = continue_scope.instructions.items.len;
6201 _ = try unusedResultExpr(&continue_scope, &continue_scope.base, while_full.ast.then_expr);6209 _ = try unusedResultExpr(&continue_scope, &continue_scope.base, then_node);
6202 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);6210 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
6203 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";6211 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
6204 if (!continue_scope.endsWithNoReturn()) {6212 if (!continue_scope.endsWithNoReturn()) {
...@@ -6261,7 +6269,7 @@ fn whileExpr(...@@ -6261,7 +6269,7 @@ fn whileExpr(
6261 .result = else_result,6269 .result = else_result,
6262 };6270 };
6263 } else .{6271 } else .{
6264 .src = while_full.ast.then_expr,6272 .src = then_node,
6265 .result = .none,6273 .result = .none,
6266 };6274 };
62676275
...@@ -6280,7 +6288,9 @@ fn whileExpr(...@@ -6280,7 +6288,9 @@ fn whileExpr(
6280 condbr,6288 condbr,
6281 cond.bool_bit,6289 cond.bool_bit,
6282 .void_value,6290 .void_value,
6291 then_node,
6283 else_info.result,6292 else_info.result,
6293 else_info.src,
6284 loop_block,6294 loop_block,
6285 cond_block,6295 cond_block,
6286 break_tag,6296 break_tag,
...@@ -6468,6 +6478,7 @@ fn forExpr(...@@ -6468,6 +6478,7 @@ fn forExpr(
6468 });6478 });
6469 }6479 }
64706480
6481 var then_node = for_full.ast.then_expr;
6471 var then_scope = parent_gz.makeSubBlock(&cond_scope.base);6482 var then_scope = parent_gz.makeSubBlock(&cond_scope.base);
6472 defer then_scope.unstack();6483 defer then_scope.unstack();
64736484
...@@ -6535,8 +6546,8 @@ fn forExpr(...@@ -6535,8 +6546,8 @@ fn forExpr(
6535 break :blk capture_sub_scope;6546 break :blk capture_sub_scope;
6536 };6547 };
65376548
6538 const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, for_full.ast.then_expr);6549 const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, then_node);
6539 _ = try addEnsureResult(&then_scope, then_result, for_full.ast.then_expr);6550 _ = try addEnsureResult(&then_scope, then_result, then_node);
65406551
6541 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);6552 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
6542 try then_scope.addDbgBlockEnd();6553 try then_scope.addDbgBlockEnd();
...@@ -6567,7 +6578,7 @@ fn forExpr(...@@ -6567,7 +6578,7 @@ fn forExpr(
6567 .result = else_result,6578 .result = else_result,
6568 };6579 };
6569 } else .{6580 } else .{
6570 .src = for_full.ast.then_expr,6581 .src = then_node,
6571 .result = .none,6582 .result = .none,
6572 };6583 };
65736584
...@@ -6587,7 +6598,9 @@ fn forExpr(...@@ -6587,7 +6598,9 @@ fn forExpr(
6587 condbr,6598 condbr,
6588 cond,6599 cond,
6589 then_result,6600 then_result,
6601 then_node,
6590 else_info.result,6602 else_info.result,
6603 else_info.src,
6591 loop_block,6604 loop_block,
6592 cond_block,6605 cond_block,
6593 break_tag,6606 break_tag,
...@@ -6949,12 +6962,13 @@ fn switchExpr(...@@ -6949,12 +6962,13 @@ fn switchExpr(
6949 if (dbg_var_tag_name) |some| {6962 if (dbg_var_tag_name) |some| {
6950 try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst);6963 try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst);
6951 }6964 }
6952 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, case.ast.target_expr);6965 const target_expr_node = case.ast.target_expr;
6966 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
6953 try checkUsed(parent_gz, &case_scope.base, sub_scope);6967 try checkUsed(parent_gz, &case_scope.base, sub_scope);
6954 try case_scope.addDbgBlockEnd();6968 try case_scope.addDbgBlockEnd();
6955 if (!parent_gz.refIsNoReturn(case_result)) {6969 if (!parent_gz.refIsNoReturn(case_result)) {
6956 block_scope.break_count += 1;6970 block_scope.break_count += 1;
6957 _ = try case_scope.addBreak(.@"break", switch_block, case_result);6971 _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node);
6958 }6972 }
69596973
6960 const case_slice = case_scope.instructionsSlice();6974 const case_slice = case_scope.instructionsSlice();
...@@ -7057,10 +7071,12 @@ fn switchExpr(...@@ -7057,10 +7071,12 @@ fn switchExpr(
7057 .break_void => {7071 .break_void => {
7058 assert(!strat.elide_store_to_block_ptr_instructions);7072 assert(!strat.elide_store_to_block_ptr_instructions);
7059 const last_inst = payloads.items[end_index - 1];7073 const last_inst = payloads.items[end_index - 1];
7060 if (zir_tags[last_inst] == .@"break" and7074 if (zir_tags[last_inst] == .@"break") {
7061 zir_datas[last_inst].@"break".block_inst == switch_block)7075 const inst_data = zir_datas[last_inst].@"break";
7062 {7076 const block_inst = astgen.extra.items[inst_data.payload_index];
7063 zir_datas[last_inst].@"break".operand = .void_value;7077 if (block_inst == switch_block) {
7078 zir_datas[last_inst].@"break".operand = .void_value;
7079 }
7064 }7080 }
7065 },7081 },
7066 }7082 }
...@@ -8856,7 +8872,7 @@ fn callExpr(...@@ -8856,7 +8872,7 @@ fn callExpr(
8856 // `call_inst` is reused to provide the param type.8872 // `call_inst` is reused to provide the param type.
8857 arg_block.rl_ty_inst = call_inst;8873 arg_block.rl_ty_inst = call_inst;
8858 const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);8874 const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);
8859 _ = try arg_block.addBreak(.break_inline, call_index, arg_ref);8875 _ = try arg_block.addBreakWithSrcNode(.break_inline, call_index, arg_ref, param_node);
88608876
8861 const body = arg_block.instructionsSlice();8877 const body = arg_block.instructionsSlice();
8862 try astgen.scratch.ensureUnusedCapacity(astgen.gpa, countBodyLenAfterFixups(astgen, body));8878 try astgen.scratch.ensureUnusedCapacity(astgen.gpa, countBodyLenAfterFixups(astgen, body));
...@@ -11262,35 +11278,40 @@ const GenZir = struct {...@@ -11262,35 +11278,40 @@ const GenZir = struct {
11262 if (align_body.len != 0) {11278 if (align_body.len != 0) {
11263 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));11279 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));
11264 astgen.appendBodyWithFixups(align_body);11280 astgen.appendBodyWithFixups(align_body);
11265 zir_datas[align_body[align_body.len - 1]].@"break".block_inst = new_index;11281 const inst_data = zir_datas[align_body[align_body.len - 1]].@"break";
11282 astgen.extra.items[inst_data.payload_index] = new_index;
11266 } else if (args.align_ref != .none) {11283 } else if (args.align_ref != .none) {
11267 astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref));11284 astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref));
11268 }11285 }
11269 if (addrspace_body.len != 0) {11286 if (addrspace_body.len != 0) {
11270 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));11287 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));
11271 astgen.appendBodyWithFixups(addrspace_body);11288 astgen.appendBodyWithFixups(addrspace_body);
11272 zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".block_inst = new_index;11289 const inst_data = zir_datas[addrspace_body[addrspace_body.len - 1]].@"break";
11290 astgen.extra.items[inst_data.payload_index] = new_index;
11273 } else if (args.addrspace_ref != .none) {11291 } else if (args.addrspace_ref != .none) {
11274 astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref));11292 astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref));
11275 }11293 }
11276 if (section_body.len != 0) {11294 if (section_body.len != 0) {
11277 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));11295 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));
11278 astgen.appendBodyWithFixups(section_body);11296 astgen.appendBodyWithFixups(section_body);
11279 zir_datas[section_body[section_body.len - 1]].@"break".block_inst = new_index;11297 const inst_data = zir_datas[section_body[section_body.len - 1]].@"break";
11298 astgen.extra.items[inst_data.payload_index] = new_index;
11280 } else if (args.section_ref != .none) {11299 } else if (args.section_ref != .none) {
11281 astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref));11300 astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref));
11282 }11301 }
11283 if (cc_body.len != 0) {11302 if (cc_body.len != 0) {
11284 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));11303 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));
11285 astgen.appendBodyWithFixups(cc_body);11304 astgen.appendBodyWithFixups(cc_body);
11286 zir_datas[cc_body[cc_body.len - 1]].@"break".block_inst = new_index;11305 const inst_data = zir_datas[cc_body[cc_body.len - 1]].@"break";
11306 astgen.extra.items[inst_data.payload_index] = new_index;
11287 } else if (args.cc_ref != .none) {11307 } else if (args.cc_ref != .none) {
11288 astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref));11308 astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref));
11289 }11309 }
11290 if (ret_body.len != 0) {11310 if (ret_body.len != 0) {
11291 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));11311 astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));
11292 astgen.appendBodyWithFixups(ret_body);11312 astgen.appendBodyWithFixups(ret_body);
11293 zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;11313 const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break";
11314 astgen.extra.items[inst_data.payload_index] = new_index;
11294 } else if (ret_ref != .none) {11315 } else if (ret_ref != .none) {
11295 astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));11316 astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
11296 }11317 }
...@@ -11344,7 +11365,9 @@ const GenZir = struct {...@@ -11344,7 +11365,9 @@ const GenZir = struct {
11344 const zir_datas = astgen.instructions.items(.data);11365 const zir_datas = astgen.instructions.items(.data);
11345 if (ret_body.len != 0) {11366 if (ret_body.len != 0) {
11346 astgen.appendBodyWithFixups(ret_body);11367 astgen.appendBodyWithFixups(ret_body);
11347 zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;11368
11369 const inst_data = zir_datas[ret_body[ret_body.len - 1]].@"break";
11370 astgen.extra.items[inst_data.payload_index] = new_index;
11348 } else if (ret_ref != .none) {11371 } else if (ret_ref != .none) {
11349 astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));11372 astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
11350 }11373 }
...@@ -11790,30 +11813,104 @@ const GenZir = struct {...@@ -11790,30 +11813,104 @@ const GenZir = struct {
11790 fn addBreak(11813 fn addBreak(
11791 gz: *GenZir,11814 gz: *GenZir,
11792 tag: Zir.Inst.Tag,11815 tag: Zir.Inst.Tag,
11793 break_block: Zir.Inst.Index,11816 block_inst: Zir.Inst.Index,
11794 operand: Zir.Inst.Ref,11817 operand: Zir.Inst.Ref,
11795 ) !Zir.Inst.Index {11818 ) !Zir.Inst.Index {
11796 return gz.addAsIndex(.{11819 const gpa = gz.astgen.gpa;
11820 try gz.instructions.ensureUnusedCapacity(gpa, 1);
11821 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
11822
11823 const extra: Zir.Inst.Break = .{
11824 .block_inst = block_inst,
11825 .operand_src_node = Zir.Inst.Break.no_src_node,
11826 };
11827 const payload_index = try gz.astgen.addExtra(extra);
11828 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
11829 gz.astgen.instructions.appendAssumeCapacity(.{
11797 .tag = tag,11830 .tag = tag,
11798 .data = .{ .@"break" = .{11831 .data = .{ .@"break" = .{
11799 .block_inst = break_block,
11800 .operand = operand,11832 .operand = operand,
11833 .payload_index = payload_index,
11801 } },11834 } },
11802 });11835 });
11836 gz.instructions.appendAssumeCapacity(new_index);
11837 return new_index;
11803 }11838 }
1180411839
11805 fn makeBreak(11840 fn makeBreak(
11806 gz: *GenZir,11841 gz: *GenZir,
11807 tag: Zir.Inst.Tag,11842 tag: Zir.Inst.Tag,
11808 break_block: Zir.Inst.Index,11843 block_inst: Zir.Inst.Index,
11809 operand: Zir.Inst.Ref,11844 operand: Zir.Inst.Ref,
11810 ) !Zir.Inst.Index {11845 ) !Zir.Inst.Index {
11846 const gpa = gz.astgen.gpa;
11847 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
11848
11849 const extra: Zir.Inst.Break = .{
11850 .block_inst = block_inst,
11851 .operand_src_node = Zir.Inst.Break.no_src_node,
11852 };
11853 const payload_index = try gz.astgen.addExtra(extra);
11811 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);11854 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
11812 try gz.astgen.instructions.append(gz.astgen.gpa, .{11855 gz.astgen.instructions.appendAssumeCapacity(.{
11813 .tag = tag,11856 .tag = tag,
11814 .data = .{ .@"break" = .{11857 .data = .{ .@"break" = .{
11815 .block_inst = break_block,
11816 .operand = operand,11858 .operand = operand,
11859 .payload_index = payload_index,
11860 } },
11861 });
11862 return new_index;
11863 }
11864
11865 fn addBreakWithSrcNode(
11866 gz: *GenZir,
11867 tag: Zir.Inst.Tag,
11868 block_inst: Zir.Inst.Index,
11869 operand: Zir.Inst.Ref,
11870 operand_src_node: Ast.Node.Index,
11871 ) !Zir.Inst.Index {
11872 const gpa = gz.astgen.gpa;
11873 try gz.instructions.ensureUnusedCapacity(gpa, 1);
11874 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
11875
11876 const extra: Zir.Inst.Break = .{
11877 .block_inst = block_inst,
11878 .operand_src_node = gz.nodeIndexToRelative(operand_src_node),
11879 };
11880 const payload_index = try gz.astgen.addExtra(extra);
11881 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
11882 gz.astgen.instructions.appendAssumeCapacity(.{
11883 .tag = tag,
11884 .data = .{ .@"break" = .{
11885 .operand = operand,
11886 .payload_index = payload_index,
11887 } },
11888 });
11889 gz.instructions.appendAssumeCapacity(new_index);
11890 return new_index;
11891 }
11892
11893 fn makeBreakWithSrcNode(
11894 gz: *GenZir,
11895 tag: Zir.Inst.Tag,
11896 block_inst: Zir.Inst.Index,
11897 operand: Zir.Inst.Ref,
11898 operand_src_node: Ast.Node.Index,
11899 ) !Zir.Inst.Index {
11900 const gpa = gz.astgen.gpa;
11901 try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
11902
11903 const extra: Zir.Inst.Break = .{
11904 .block_inst = block_inst,
11905 .operand_src_node = gz.nodeIndexToRelative(operand_src_node),
11906 };
11907 const payload_index = try gz.astgen.addExtra(extra);
11908 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
11909 gz.astgen.instructions.appendAssumeCapacity(.{
11910 .tag = tag,
11911 .data = .{ .@"break" = .{
11912 .operand = operand,
11913 .payload_index = payload_index,
11817 } },11914 } },
11818 });11915 });
11819 return new_index;11916 return new_index;
src/Module.zig+1-1
...@@ -5949,7 +5949,7 @@ pub const PeerTypeCandidateSrc = union(enum) {...@@ -5949,7 +5949,7 @@ pub const PeerTypeCandidateSrc = union(enum) {
5949 none: void,5949 none: void,
5950 /// When we want to know the the src of candidate i, look up at5950 /// When we want to know the the src of candidate i, look up at
5951 /// index i in this slice5951 /// index i in this slice
5952 override: []LazySrcLoc,5952 override: []?LazySrcLoc,
5953 /// resolvePeerTypes originates from a @TypeOf(...) call5953 /// resolvePeerTypes originates from a @TypeOf(...) call
5954 typeof_builtin_call_node_offset: i32,5954 typeof_builtin_call_node_offset: i32,
59555955
src/Sema.zig+47-28
...@@ -349,6 +349,16 @@ pub const Block = struct {...@@ -349,6 +349,16 @@ pub const Block = struct {
349 /// if we need to add type coercion at the end of block analysis.349 /// if we need to add type coercion at the end of block analysis.
350 /// Same indexes, capacity, length as `results`.350 /// Same indexes, capacity, length as `results`.
351 br_list: std.ArrayListUnmanaged(Air.Inst.Index),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 };
353363
354 /// For debugging purposes.364 /// For debugging purposes.
...@@ -722,8 +732,7 @@ const LabeledBlock = struct {...@@ -722,8 +732,7 @@ const LabeledBlock = struct {
722732
723 fn destroy(lb: *LabeledBlock, gpa: Allocator) void {733 fn destroy(lb: *LabeledBlock, gpa: Allocator) void {
724 lb.block.instructions.deinit(gpa);734 lb.block.instructions.deinit(gpa);
725 lb.label.merges.results.deinit(gpa);735 lb.label.merges.deinit(gpa);
726 lb.label.merges.br_list.deinit(gpa);
727 gpa.destroy(lb);736 gpa.destroy(lb);
728 }737 }
729};738};
...@@ -777,8 +786,9 @@ fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.In...@@ -777,8 +786,9 @@ fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.In
777 error.ComptimeBreak => {786 error.ComptimeBreak => {
778 const zir_datas = sema.code.instructions.items(.data);787 const zir_datas = sema.code.instructions.items(.data);
779 const break_data = zir_datas[sema.comptime_break_inst].@"break";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 try sema.addRuntimeBreak(block, .{790 try sema.addRuntimeBreak(block, .{
781 .block_inst = break_data.block_inst,791 .block_inst = extra.block_inst,
782 .operand = break_data.operand,792 .operand = break_data.operand,
783 .inst = sema.comptime_break_inst,793 .inst = sema.comptime_break_inst,
784 });794 });
...@@ -817,8 +827,9 @@ pub fn analyzeBodyBreak(...@@ -817,8 +827,9 @@ pub fn analyzeBodyBreak(
817 sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn())827 sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn())
818 return null;828 return null;
819 const break_data = sema.code.instructions.items(.data)[break_inst].@"break";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 return BreakData{831 return BreakData{
821 .block_inst = break_data.block_inst,832 .block_inst = extra.block_inst,
822 .operand = break_data.operand,833 .operand = break_data.operand,
823 .inst = break_inst,834 .inst = break_inst,
824 };835 };
...@@ -5238,6 +5249,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5238,6 +5249,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5238 var label: Block.Label = .{5249 var label: Block.Label = .{
5239 .zir_block = inst,5250 .zir_block = inst,
5240 .merges = .{5251 .merges = .{
5252 .src_locs = .{},
5241 .results = .{},5253 .results = .{},
5242 .br_list = .{},5254 .br_list = .{},
5243 .block_inst = block_inst,5255 .block_inst = block_inst,
...@@ -5251,8 +5263,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5251,8 +5263,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5251 const merges = &child_block.label.?.merges;5263 const merges = &child_block.label.?.merges;
52525264
5253 defer child_block.instructions.deinit(gpa);5265 defer child_block.instructions.deinit(gpa);
5254 defer merges.results.deinit(gpa);5266 defer merges.deinit(gpa);
5255 defer merges.br_list.deinit(gpa);
52565267
5257 var loop_block = child_block.makeSubBlock();5268 var loop_block = child_block.makeSubBlock();
5258 defer loop_block.instructions.deinit(gpa);5269 defer loop_block.instructions.deinit(gpa);
...@@ -5422,6 +5433,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5422,6 +5433,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5422 var label: Block.Label = .{5433 var label: Block.Label = .{
5423 .zir_block = inst,5434 .zir_block = inst,
5424 .merges = .{5435 .merges = .{
5436 .src_locs = .{},
5425 .results = .{},5437 .results = .{},
5426 .br_list = .{},5438 .br_list = .{},
5427 .block_inst = block_inst,5439 .block_inst = block_inst,
...@@ -5450,8 +5462,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -5450,8 +5462,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
5450 };5462 };
54515463
5452 defer child_block.instructions.deinit(gpa);5464 defer child_block.instructions.deinit(gpa);
5453 defer label.merges.results.deinit(gpa);5465 defer label.merges.deinit(gpa);
5454 defer label.merges.br_list.deinit(gpa);
54555466
5456 return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);5467 return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
5457}5468}
...@@ -5480,7 +5491,8 @@ fn resolveBlockBody(...@@ -5480,7 +5491,8 @@ fn resolveBlockBody(
54805491
5481 const break_inst = sema.comptime_break_inst;5492 const break_inst = sema.comptime_break_inst;
5482 const break_data = sema.code.instructions.items(.data)[break_inst].@"break";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 return try sema.resolveInst(break_data.operand);5496 return try sema.resolveInst(break_data.operand);
5485 } else {5497 } else {
5486 return error.ComptimeBreak;5498 return error.ComptimeBreak;
...@@ -5533,7 +5545,7 @@ fn analyzeBlockBody(...@@ -5533,7 +5545,7 @@ fn analyzeBlockBody(
5533 // Need to set the type and emit the Block instruction. This allows machine code generation5545 // Need to set the type and emit the Block instruction. This allows machine code generation
5534 // to emit a jump instruction to after the block when it encounters the break.5546 // to emit a jump instruction to after the block when it encounters the break.
5535 try parent_block.instructions.append(gpa, merges.block_inst);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 // TODO add note "missing else causes void value"5549 // TODO add note "missing else causes void value"
55385550
5539 const type_src = src; // TODO: better source location5551 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,14 +5854,20 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
5842 defer tracy.end();5854 defer tracy.end();
58435855
5844 const inst_data = sema.code.instructions.items(.data)[inst].@"break";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 const operand = try sema.resolveInst(inst_data.operand);5858 const operand = try sema.resolveInst(inst_data.operand);
5846 const zir_block = inst_data.block_inst;5859 const zir_block = extra.block_inst;
58475860
5848 var block = start_block;5861 var block = start_block;
5849 while (true) {5862 while (true) {
5850 if (block.label) |label| {5863 if (block.label) |label| {
5851 if (label.zir_block == zir_block) {5864 if (label.zir_block == zir_block) {
5852 const br_ref = try start_block.addBr(label.merges.block_inst, operand);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 try label.merges.results.append(sema.gpa, operand);5871 try label.merges.results.append(sema.gpa, operand);
5854 try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);5872 try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);
5855 block.runtime_index.increment();5873 block.runtime_index.increment();
...@@ -6643,6 +6661,7 @@ fn analyzeCall(...@@ -6643,6 +6661,7 @@ fn analyzeCall(
6643 .func = null,6661 .func = null,
6644 .comptime_result = undefined,6662 .comptime_result = undefined,
6645 .merges = .{6663 .merges = .{
6664 .src_locs = .{},
6646 .results = .{},6665 .results = .{},
6647 .br_list = .{},6666 .br_list = .{},
6648 .block_inst = block_inst,6667 .block_inst = block_inst,
...@@ -6692,8 +6711,7 @@ fn analyzeCall(...@@ -6692,8 +6711,7 @@ fn analyzeCall(
6692 const merges = &child_block.inlining.?.merges;6711 const merges = &child_block.inlining.?.merges;
66936712
6694 defer child_block.instructions.deinit(gpa);6713 defer child_block.instructions.deinit(gpa);
6695 defer merges.results.deinit(gpa);6714 defer merges.deinit(gpa);
6696 defer merges.br_list.deinit(gpa);
66976715
6698 // If it's a comptime function call, we need to memoize it as long as no external6716 // If it's a comptime function call, we need to memoize it as long as no external
6699 // comptime memory is mutated.6717 // comptime memory is mutated.
...@@ -10780,6 +10798,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10780,6 +10798,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10780 var label: Block.Label = .{10798 var label: Block.Label = .{
10781 .zir_block = inst,10799 .zir_block = inst,
10782 .merges = .{10800 .merges = .{
10801 .src_locs = .{},
10783 .results = .{},10802 .results = .{},
10784 .br_list = .{},10803 .br_list = .{},
10785 .block_inst = block_inst,10804 .block_inst = block_inst,
...@@ -10807,8 +10826,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10807,8 +10826,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10807 };10826 };
10808 const merges = &child_block.label.?.merges;10827 const merges = &child_block.label.?.merges;
10809 defer child_block.instructions.deinit(gpa);10828 defer child_block.instructions.deinit(gpa);
10810 defer merges.results.deinit(gpa);10829 defer merges.deinit(gpa);
10811 defer merges.br_list.deinit(gpa);
1081210830
10813 if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {10831 if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| {
10814 var extra_index: usize = special.end;10832 var extra_index: usize = special.end;
...@@ -12298,7 +12316,7 @@ fn zirBitwise(...@@ -12298,7 +12316,7 @@ fn zirBitwise(
12298 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);12316 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1229912317
12300 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };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 const scalar_type = resolved_type.scalarType();12320 const scalar_type = resolved_type.scalarType();
12303 const scalar_tag = scalar_type.zigTypeTag();12321 const scalar_tag = scalar_type.zigTypeTag();
1230412322
...@@ -12502,7 +12520,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12502,7 +12520,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12502 try trash_block.addBitCast(rhs_info.elem_type, .void_value),12520 try trash_block.addBitCast(rhs_info.elem_type, .void_value),
12503 };12521 };
12504 break :t try sema.resolvePeerTypes(block, src, &instructions, .{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 };
1250812526
...@@ -13002,7 +13020,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -13002,7 +13020,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1300213020
13003 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };13021 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13004 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{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 });
1300713025
13008 const is_vector = resolved_type.zigTypeTag() == .Vector;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,7 +13180,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1316213180
13163 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };13181 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13164 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{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 });
1316713185
13168 const is_vector = resolved_type.zigTypeTag() == .Vector;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,7 +13343,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1332513343
13326 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };13344 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13327 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{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 });
1333013348
13331 const is_vector = resolved_type.zigTypeTag() == .Vector;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,7 +13459,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1344113459
13442 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };13460 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13443 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{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 });
1344613464
13447 const is_vector = resolved_type.zigTypeTag() == .Vector;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,7 +13701,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1368313701
13684 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };13702 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13685 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{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 });
1368813706
13689 const is_vector = resolved_type.zigTypeTag() == .Vector;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,7 +13884,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1386613884
13867 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };13885 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13868 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{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 });
1387113889
13872 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);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,7 +13986,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1396813986
13969 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };13987 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
13970 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{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 });
1397313991
13974 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);13992 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
...@@ -14081,7 +14099,7 @@ fn zirOverflowArithmetic(...@@ -14081,7 +14099,7 @@ fn zirOverflowArithmetic(
14081 lhs_ty14099 lhs_ty
14082 else14100 else
14083 try sema.resolvePeerTypes(block, src, instructions, .{14101 try sema.resolvePeerTypes(block, src, instructions, .{
14084 .override = &[_]LazySrcLoc{ lhs_src, rhs_src },14102 .override = &[_]?LazySrcLoc{ lhs_src, rhs_src },
14085 });14103 });
1408614104
14087 const rhs_dest_ty = if (zir_tag == .shl_with_overflow)14105 const rhs_dest_ty = if (zir_tag == .shl_with_overflow)
...@@ -14312,7 +14330,7 @@ fn analyzeArithmetic(...@@ -14312,7 +14330,7 @@ fn analyzeArithmetic(
1431214330
14313 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };14331 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
14314 const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{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 });
1431714335
14318 const is_vector = resolved_type.zigTypeTag() == .Vector;14336 const is_vector = resolved_type.zigTypeTag() == .Vector;
...@@ -15200,7 +15218,7 @@ fn analyzeCmp(...@@ -15200,7 +15218,7 @@ fn analyzeCmp(
15200 return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);15218 return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
15201 }15219 }
15202 const instructions = &[_]Air.Inst.Ref{ lhs, rhs };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 if (!resolved_type.isSelfComparable(is_equality_cmp)) {15222 if (!resolved_type.isSelfComparable(is_equality_cmp)) {
15205 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{15223 return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{
15206 compareOperatorName(op), resolved_type.fmt(sema.mod),15224 compareOperatorName(op), resolved_type.fmt(sema.mod),
...@@ -17024,6 +17042,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi...@@ -17024,6 +17042,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi
17024 .label = .{17042 .label = .{
17025 .zir_block = break_data.block_inst,17043 .zir_block = break_data.block_inst,
17026 .merges = .{17044 .merges = .{
17045 .src_locs = .{},
17027 .results = .{},17046 .results = .{},
17028 .br_list = .{},17047 .br_list = .{},
17029 .block_inst = new_block_inst,17048 .block_inst = new_block_inst,
...@@ -20605,7 +20624,7 @@ fn checkSimdBinOp(...@@ -20605,7 +20624,7 @@ fn checkSimdBinOp(
20605 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);20624 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
20606 var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null;20625 var vec_len: ?usize = if (lhs_ty.zigTypeTag() == .Vector) lhs_ty.vectorLen() else null;
20607 const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{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 const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src);20629 const lhs = try sema.coerce(block, result_ty, uncasted_lhs, lhs_src);
20611 const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src);20630 const rhs = try sema.coerce(block, result_ty, uncasted_rhs, rhs_src);
src/Zir.zig+8-1
...@@ -2603,8 +2603,8 @@ pub const Inst = struct {...@@ -2603,8 +2603,8 @@ pub const Inst = struct {
2603 }2603 }
2604 },2604 },
2605 @"break": struct {2605 @"break": struct {
2606 block_inst: Index,
2607 operand: Ref,2606 operand: Ref,
2607 payload_index: u32,
2608 },2608 },
2609 switch_capture: struct {2609 switch_capture: struct {
2610 switch_inst: Index,2610 switch_inst: Index,
...@@ -2690,6 +2690,13 @@ pub const Inst = struct {...@@ -2690,6 +2690,13 @@ pub const Inst = struct {
2690 };2690 };
2691 };2691 };
26922692
2693 pub const Break = struct {
2694 pub const no_src_node = std.math.maxInt(i32);
2695
2696 block_inst: Index,
2697 operand_src_node: i32,
2698 };
2699
2693 /// Trailing:2700 /// Trailing:
2694 /// 0. Output for every outputs_len2701 /// 0. Output for every outputs_len
2695 /// 1. Input for every inputs_len2702 /// 1. Input for every inputs_len
src/print_zir.zig+2-1
...@@ -2321,8 +2321,9 @@ const Writer = struct {...@@ -2321,8 +2321,9 @@ const Writer = struct {
23212321
2322 fn writeBreak(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {2322 fn writeBreak(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
2323 const inst_data = self.code.instructions.items(.data)[inst].@"break";2323 const inst_data = self.code.instructions.items(.data)[inst].@"break";
2324 const extra = self.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
23242325
2325 try self.writeInstIndex(stream, inst_data.block_inst);2326 try self.writeInstIndex(stream, extra.block_inst);
2326 try stream.writeAll(", ");2327 try stream.writeAll(", ");
2327 try self.writeInstRef(stream, inst_data.operand);2328 try self.writeInstRef(stream, inst_data.operand);
2328 try stream.writeAll(")");2329 try stream.writeAll(")");
test/cases/compile_errors/incompatible sub-byte fields.zig +2
...@@ -25,3 +25,5 @@ export fn entry() void {...@@ -25,3 +25,5 @@ export fn entry() void {
25// target=native25// target=native
26//26//
27// :14:17: error: incompatible types: '*align(1:0:1) u2' and '*align(2:8:2) u2'27// :14:17: error: incompatible types: '*align(1:0:1) u2' and '*align(2:8:2) u2'
28// :15:14: note: type '*align(1:0:1) u2' here
29// :16:14: note: type '*align(2:8:2) u2' here
test/cases/compile_errors/missing_else_clause.zig+2
...@@ -31,7 +31,9 @@ export fn entry() void {...@@ -31,7 +31,9 @@ export fn entry() void {
31// target=native31// target=native
32//32//
33// :2:21: error: incompatible types: 'i32' and 'void'33// :2:21: error: incompatible types: 'i32' and 'void'
34// :6:25: note: type 'i32' here
34// :6:15: error: incompatible types: 'i32' and 'void'35// :6:15: error: incompatible types: 'i32' and 'void'
36// :2:31: note: type 'i32' here
35// :12:16: error: expected type 'tmp.h.T', found 'void'37// :12:16: error: expected type 'tmp.h.T', found 'void'
36// :11:15: note: struct declared here38// :11:15: note: struct declared here
37// :18:9: error: incompatible types: 'void' and 'tmp.k.T'39// :18:9: error: incompatible types: 'void' and 'tmp.k.T'
test/cases/compile_errors/missing_result_type_for_phi_node.zig+2
...@@ -10,3 +10,5 @@ export fn entry() void {...@@ -10,3 +10,5 @@ export fn entry() void {
10// target=native10// target=native
11//11//
12// :5:11: error: incompatible types: 'void' and 'comptime_int'12// :5:11: error: incompatible types: 'void' and 'comptime_int'
13// :5:11: note: type 'void' here
14// :5:17: note: type 'comptime_int' here
test/cases/compile_errors/unused_value_in_switch_in_loop.zig+2
...@@ -12,3 +12,5 @@ export fn entry() void {...@@ -12,3 +12,5 @@ export fn entry() void {
12// target=native12// target=native
13//13//
14// :3:18: error: incompatible types: 'comptime_int' and 'void'14// :3:18: error: incompatible types: 'comptime_int' and 'void'
15// :4:14: note: type 'comptime_int' here
16// :5:16: note: type 'void' here