authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-02 04:52:19+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-03-02 04:52:19+00:00
log9d500bda2d09fe67c39ee98067c1e53c58adbd5e
treef841a65fdab25a8025835055722d994d3040a9a1
parent64f77f32df7656c3d7613d402b332f071ea15557
parent6a87e42c2ea070a6273317bbb005029d95ceae49
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19117 from mlugg/dbg-var-blocks

Major ZIR size optimizations & small cleanups in Sema

5 files changed, 422 insertions(+), 302 deletions(-)

lib/std/zig/AstGen.zig+114-35
...@@ -1232,7 +1232,7 @@ fn suspendExpr(...@@ -1232,7 +1232,7 @@ fn suspendExpr(
1232 suspend_scope.suspend_node = node;1232 suspend_scope.suspend_node = node;
1233 defer suspend_scope.unstack();1233 defer suspend_scope.unstack();
12341234
1235 const body_result = try expr(&suspend_scope, &suspend_scope.base, .{ .rl = .none }, body_node);1235 const body_result = try fullBodyExpr(&suspend_scope, &suspend_scope.base, .{ .rl = .none }, body_node);
1236 if (!gz.refIsNoReturn(body_result)) {1236 if (!gz.refIsNoReturn(body_result)) {
1237 _ = try suspend_scope.addBreak(.break_inline, suspend_inst, .void_value);1237 _ = try suspend_scope.addBreak(.break_inline, suspend_inst, .void_value);
1238 }1238 }
...@@ -1353,7 +1353,7 @@ fn fnProtoExpr(...@@ -1353,7 +1353,7 @@ fn fnProtoExpr(
1353 assert(param_type_node != 0);1353 assert(param_type_node != 0);
1354 var param_gz = block_scope.makeSubBlock(scope);1354 var param_gz = block_scope.makeSubBlock(scope);
1355 defer param_gz.unstack();1355 defer param_gz.unstack();
1356 const param_type = try expr(&param_gz, scope, coerced_type_ri, param_type_node);1356 const param_type = try fullBodyExpr(&param_gz, scope, coerced_type_ri, param_type_node);
1357 const param_inst_expected: Zir.Inst.Index = @enumFromInt(astgen.instructions.len + 1);1357 const param_inst_expected: Zir.Inst.Index = @enumFromInt(astgen.instructions.len + 1);
1358 _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node);1358 _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node);
1359 const main_tokens = tree.nodes.items(.main_token);1359 const main_tokens = tree.nodes.items(.main_token);
...@@ -2060,7 +2060,7 @@ fn comptimeExpr(...@@ -2060,7 +2060,7 @@ fn comptimeExpr(
2060 else2060 else
2061 .none,2061 .none,
2062 };2062 };
2063 const block_result = try expr(&block_scope, scope, ty_only_ri, node);2063 const block_result = try fullBodyExpr(&block_scope, scope, ty_only_ri, node);
2064 if (!gz.refIsNoReturn(block_result)) {2064 if (!gz.refIsNoReturn(block_result)) {
2065 _ = try block_scope.addBreak(.@"break", block_inst, block_result);2065 _ = try block_scope.addBreak(.@"break", block_inst, block_result);
2066 }2066 }
...@@ -2291,6 +2291,53 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)...@@ -2291,6 +2291,53 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
2291 }2291 }
2292}2292}
22932293
2294/// Similar to `expr`, but intended for use when `gz` corresponds to a body
2295/// which will contain only this node's code. Differs from `expr` in that if the
2296/// root expression is an unlabeled block, does not emit an actual block.
2297/// Instead, the block contents are emitted directly into `gz`.
2298fn fullBodyExpr(
2299 gz: *GenZir,
2300 scope: *Scope,
2301 ri: ResultInfo,
2302 node: Ast.Node.Index,
2303) InnerError!Zir.Inst.Ref {
2304 const tree = gz.astgen.tree;
2305 const node_tags = tree.nodes.items(.tag);
2306 const node_datas = tree.nodes.items(.data);
2307 const main_tokens = tree.nodes.items(.main_token);
2308 const token_tags = tree.tokens.items(.tag);
2309 var stmt_buf: [2]Ast.Node.Index = undefined;
2310 const statements: []const Ast.Node.Index = switch (node_tags[node]) {
2311 else => return expr(gz, scope, ri, node),
2312 .block_two, .block_two_semicolon => if (node_datas[node].lhs == 0) s: {
2313 break :s &.{};
2314 } else if (node_datas[node].rhs == 0) s: {
2315 stmt_buf[0] = node_datas[node].lhs;
2316 break :s stmt_buf[0..1];
2317 } else s: {
2318 stmt_buf[0] = node_datas[node].lhs;
2319 stmt_buf[1] = node_datas[node].rhs;
2320 break :s stmt_buf[0..2];
2321 },
2322 .block, .block_semicolon => tree.extra_data[node_datas[node].lhs..node_datas[node].rhs],
2323 };
2324
2325 const lbrace = main_tokens[node];
2326 if (token_tags[lbrace - 1] == .colon and
2327 token_tags[lbrace - 2] == .identifier)
2328 {
2329 // Labeled blocks are tricky - forwarding result location information properly is non-trivial,
2330 // plus if this block is exited with a `break_inline` we aren't allowed multiple breaks. This
2331 // case is rare, so just treat it as a normal expression and create a nested block.
2332 return expr(gz, scope, ri, node);
2333 }
2334
2335 var sub_gz = gz.makeSubBlock(scope);
2336 try blockExprStmts(&sub_gz, &sub_gz.base, statements);
2337
2338 return rvalue(gz, ri, .void_value, node);
2339}
2340
2294fn blockExpr(2341fn blockExpr(
2295 gz: *GenZir,2342 gz: *GenZir,
2296 scope: *Scope,2343 scope: *Scope,
...@@ -2516,7 +2563,9 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod...@@ -2516,7 +2563,9 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
2516 }2563 }
2517 }2564 }
25182565
2519 try genDefers(gz, parent_scope, scope, .normal_only);2566 if (noreturn_src_node == 0) {
2567 try genDefers(gz, parent_scope, scope, .normal_only);
2568 }
2520 try checkUsed(gz, parent_scope, scope);2569 try checkUsed(gz, parent_scope, scope);
2521}2570}
25222571
...@@ -4102,7 +4151,7 @@ fn fnDecl(...@@ -4102,7 +4151,7 @@ fn fnDecl(
4102 assert(param_type_node != 0);4151 assert(param_type_node != 0);
4103 var param_gz = decl_gz.makeSubBlock(scope);4152 var param_gz = decl_gz.makeSubBlock(scope);
4104 defer param_gz.unstack();4153 defer param_gz.unstack();
4105 const param_type = try expr(&param_gz, params_scope, coerced_type_ri, param_type_node);4154 const param_type = try fullBodyExpr(&param_gz, params_scope, coerced_type_ri, param_type_node);
4106 const param_inst_expected: Zir.Inst.Index = @enumFromInt(astgen.instructions.len + 1);4155 const param_inst_expected: Zir.Inst.Index = @enumFromInt(astgen.instructions.len + 1);
4107 _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node);4156 _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node);
41084157
...@@ -4220,7 +4269,7 @@ fn fnDecl(...@@ -4220,7 +4269,7 @@ fn fnDecl(
4220 var ret_gz = decl_gz.makeSubBlock(params_scope);4269 var ret_gz = decl_gz.makeSubBlock(params_scope);
4221 defer ret_gz.unstack();4270 defer ret_gz.unstack();
4222 const ret_ref: Zir.Inst.Ref = inst: {4271 const ret_ref: Zir.Inst.Ref = inst: {
4223 const inst = try expr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type);4272 const inst = try fullBodyExpr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type);
4224 if (ret_gz.instructionsSlice().len == 0) {4273 if (ret_gz.instructionsSlice().len == 0) {
4225 // In this case we will send a len=0 body which can be encoded more efficiently.4274 // In this case we will send a len=0 body which can be encoded more efficiently.
4226 break :inst inst;4275 break :inst inst;
...@@ -4285,7 +4334,7 @@ fn fnDecl(...@@ -4285,7 +4334,7 @@ fn fnDecl(
4285 const lbrace_line = astgen.source_line - decl_gz.decl_line;4334 const lbrace_line = astgen.source_line - decl_gz.decl_line;
4286 const lbrace_column = astgen.source_column;4335 const lbrace_column = astgen.source_column;
42874336
4288 _ = try expr(&fn_gz, params_scope, .{ .rl = .none }, body_node);4337 _ = try fullBodyExpr(&fn_gz, params_scope, .{ .rl = .none }, body_node);
4289 try checkUsed(gz, &fn_gz.base, params_scope);4338 try checkUsed(gz, &fn_gz.base, params_scope);
42904339
4291 if (!fn_gz.endsWithNoReturn()) {4340 if (!fn_gz.endsWithNoReturn()) {
...@@ -4471,19 +4520,19 @@ fn globalVarDecl(...@@ -4471,19 +4520,19 @@ fn globalVarDecl(
44714520
4472 var align_gz = block_scope.makeSubBlock(scope);4521 var align_gz = block_scope.makeSubBlock(scope);
4473 if (var_decl.ast.align_node != 0) {4522 if (var_decl.ast.align_node != 0) {
4474 const align_inst = try expr(&align_gz, &align_gz.base, coerced_align_ri, var_decl.ast.align_node);4523 const align_inst = try fullBodyExpr(&align_gz, &align_gz.base, coerced_align_ri, var_decl.ast.align_node);
4475 _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, align_inst, node);4524 _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, align_inst, node);
4476 }4525 }
44774526
4478 var linksection_gz = align_gz.makeSubBlock(scope);4527 var linksection_gz = align_gz.makeSubBlock(scope);
4479 if (var_decl.ast.section_node != 0) {4528 if (var_decl.ast.section_node != 0) {
4480 const linksection_inst = try expr(&linksection_gz, &linksection_gz.base, coerced_linksection_ri, var_decl.ast.section_node);4529 const linksection_inst = try fullBodyExpr(&linksection_gz, &linksection_gz.base, coerced_linksection_ri, var_decl.ast.section_node);
4481 _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, linksection_inst, node);4530 _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, linksection_inst, node);
4482 }4531 }
44834532
4484 var addrspace_gz = linksection_gz.makeSubBlock(scope);4533 var addrspace_gz = linksection_gz.makeSubBlock(scope);
4485 if (var_decl.ast.addrspace_node != 0) {4534 if (var_decl.ast.addrspace_node != 0) {
4486 const addrspace_inst = try expr(&addrspace_gz, &addrspace_gz.base, coerced_addrspace_ri, var_decl.ast.addrspace_node);4535 const addrspace_inst = try fullBodyExpr(&addrspace_gz, &addrspace_gz.base, coerced_addrspace_ri, var_decl.ast.addrspace_node);
4487 _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, addrspace_inst, node);4536 _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, addrspace_inst, node);
4488 }4537 }
44894538
...@@ -4532,7 +4581,7 @@ fn comptimeDecl(...@@ -4532,7 +4581,7 @@ fn comptimeDecl(
4532 };4581 };
4533 defer decl_block.unstack();4582 defer decl_block.unstack();
45344583
4535 const block_result = try expr(&decl_block, &decl_block.base, .{ .rl = .none }, body_node);4584 const block_result = try fullBodyExpr(&decl_block, &decl_block.base, .{ .rl = .none }, body_node);
4536 if (decl_block.isEmpty() or !decl_block.refIsNoReturn(block_result)) {4585 if (decl_block.isEmpty() or !decl_block.refIsNoReturn(block_result)) {
4537 _ = try decl_block.addBreak(.break_inline, decl_inst, .void_value);4586 _ = try decl_block.addBreak(.break_inline, decl_inst, .void_value);
4538 }4587 }
...@@ -4734,7 +4783,7 @@ fn testDecl(...@@ -4734,7 +4783,7 @@ fn testDecl(
4734 const lbrace_line = astgen.source_line - decl_block.decl_line;4783 const lbrace_line = astgen.source_line - decl_block.decl_line;
4735 const lbrace_column = astgen.source_column;4784 const lbrace_column = astgen.source_column;
47364785
4737 const block_result = try expr(&fn_block, &fn_block.base, .{ .rl = .none }, body_node);4786 const block_result = try fullBodyExpr(&fn_block, &fn_block.base, .{ .rl = .none }, body_node);
4738 if (fn_block.isEmpty() or !fn_block.refIsNoReturn(block_result)) {4787 if (fn_block.isEmpty() or !fn_block.refIsNoReturn(block_result)) {
47394788
4740 // As our last action before the return, "pop" the error trace if needed4789 // As our last action before the return, "pop" the error trace if needed
...@@ -5981,7 +6030,7 @@ fn orelseCatchExpr(...@@ -5981,7 +6030,7 @@ fn orelseCatchExpr(
5981 break :blk &err_val_scope.base;6030 break :blk &err_val_scope.base;
5982 };6031 };
59836032
5984 const else_result = try expr(&else_scope, else_sub_scope, block_scope.break_result_info, rhs);6033 const else_result = try fullBodyExpr(&else_scope, else_sub_scope, block_scope.break_result_info, rhs);
5985 if (!else_scope.endsWithNoReturn()) {6034 if (!else_scope.endsWithNoReturn()) {
5986 // As our last action before the break, "pop" the error trace if needed6035 // As our last action before the break, "pop" the error trace if needed
5987 if (do_err_trace)6036 if (do_err_trace)
...@@ -6149,7 +6198,7 @@ fn boolBinOp(...@@ -6149,7 +6198,7 @@ fn boolBinOp(
61496198
6150 var rhs_scope = gz.makeSubBlock(scope);6199 var rhs_scope = gz.makeSubBlock(scope);
6151 defer rhs_scope.unstack();6200 defer rhs_scope.unstack();
6152 const rhs = try expr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, node_datas[node].rhs);6201 const rhs = try fullBodyExpr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, node_datas[node].rhs);
6153 if (!gz.refIsNoReturn(rhs)) {6202 if (!gz.refIsNoReturn(rhs)) {
6154 _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs);6203 _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs);
6155 }6204 }
...@@ -6293,7 +6342,7 @@ fn ifExpr(...@@ -6293,7 +6342,7 @@ fn ifExpr(
6293 }6342 }
6294 };6343 };
62956344
6296 const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node);6345 const then_result = try fullBodyExpr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node);
6297 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);6346 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
6298 if (!then_scope.endsWithNoReturn()) {6347 if (!then_scope.endsWithNoReturn()) {
6299 _ = try then_scope.addBreakWithSrcNode(.@"break", block, then_result, then_node);6348 _ = try then_scope.addBreakWithSrcNode(.@"break", block, then_result, then_node);
...@@ -6335,7 +6384,7 @@ fn ifExpr(...@@ -6335,7 +6384,7 @@ fn ifExpr(
6335 break :s &else_scope.base;6384 break :s &else_scope.base;
6336 }6385 }
6337 };6386 };
6338 const else_result = try expr(&else_scope, sub_scope, block_scope.break_result_info, else_node);6387 const else_result = try fullBodyExpr(&else_scope, sub_scope, block_scope.break_result_info, else_node);
6339 if (!else_scope.endsWithNoReturn()) {6388 if (!else_scope.endsWithNoReturn()) {
6340 // As our last action before the break, "pop" the error trace if needed6389 // As our last action before the break, "pop" the error trace if needed
6341 if (do_err_trace)6390 if (do_err_trace)
...@@ -6444,7 +6493,7 @@ fn whileExpr(...@@ -6444,7 +6493,7 @@ fn whileExpr(
6444 } = c: {6493 } = c: {
6445 if (while_full.error_token) |_| {6494 if (while_full.error_token) |_| {
6446 const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none };6495 const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none };
6447 const err_union = try expr(&cond_scope, &cond_scope.base, cond_ri, while_full.ast.cond_expr);6496 const err_union = try fullBodyExpr(&cond_scope, &cond_scope.base, cond_ri, while_full.ast.cond_expr);
6448 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err;6497 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err;
6449 break :c .{6498 break :c .{
6450 .inst = err_union,6499 .inst = err_union,
...@@ -6452,14 +6501,14 @@ fn whileExpr(...@@ -6452,14 +6501,14 @@ fn whileExpr(
6452 };6501 };
6453 } else if (while_full.payload_token) |_| {6502 } else if (while_full.payload_token) |_| {
6454 const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none };6503 const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none };
6455 const optional = try expr(&cond_scope, &cond_scope.base, cond_ri, while_full.ast.cond_expr);6504 const optional = try fullBodyExpr(&cond_scope, &cond_scope.base, cond_ri, while_full.ast.cond_expr);
6456 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;6505 const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null;
6457 break :c .{6506 break :c .{
6458 .inst = optional,6507 .inst = optional,
6459 .bool_bit = try cond_scope.addUnNode(tag, optional, while_full.ast.cond_expr),6508 .bool_bit = try cond_scope.addUnNode(tag, optional, while_full.ast.cond_expr),
6460 };6509 };
6461 } else {6510 } else {
6462 const cond = try expr(&cond_scope, &cond_scope.base, coerced_bool_ri, while_full.ast.cond_expr);6511 const cond = try fullBodyExpr(&cond_scope, &cond_scope.base, coerced_bool_ri, while_full.ast.cond_expr);
6463 break :c .{6512 break :c .{
6464 .inst = cond,6513 .inst = cond,
6465 .bool_bit = cond,6514 .bool_bit = cond,
...@@ -6582,7 +6631,11 @@ fn whileExpr(...@@ -6582,7 +6631,11 @@ fn whileExpr(
6582 }6631 }
65836632
6584 continue_scope.instructions_top = continue_scope.instructions.items.len;6633 continue_scope.instructions_top = continue_scope.instructions.items.len;
6585 _ = try unusedResultExpr(&continue_scope, &continue_scope.base, then_node);6634 {
6635 try emitDbgNode(&continue_scope, then_node);
6636 const unused_result = try fullBodyExpr(&continue_scope, &continue_scope.base, .{ .rl = .none }, then_node);
6637 _ = try addEnsureResult(&continue_scope, unused_result, then_node);
6638 }
6586 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);6639 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
6587 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";6640 const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
6588 if (!continue_scope.endsWithNoReturn()) {6641 if (!continue_scope.endsWithNoReturn()) {
...@@ -6626,7 +6679,7 @@ fn whileExpr(...@@ -6626,7 +6679,7 @@ fn whileExpr(
6626 // control flow apply to outer loops; not this one.6679 // control flow apply to outer loops; not this one.
6627 loop_scope.continue_block = .none;6680 loop_scope.continue_block = .none;
6628 loop_scope.break_block = .none;6681 loop_scope.break_block = .none;
6629 const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_info, else_node);6682 const else_result = try fullBodyExpr(&else_scope, sub_scope, loop_scope.break_result_info, else_node);
6630 if (is_statement) {6683 if (is_statement) {
6631 _ = try addEnsureResult(&else_scope, else_result, else_node);6684 _ = try addEnsureResult(&else_scope, else_result, else_node);
6632 }6685 }
...@@ -6894,7 +6947,7 @@ fn forExpr(...@@ -6894,7 +6947,7 @@ fn forExpr(
6894 break :blk capture_sub_scope;6947 break :blk capture_sub_scope;
6895 };6948 };
68966949
6897 const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, then_node);6950 const then_result = try fullBodyExpr(&then_scope, then_sub_scope, .{ .rl = .none }, then_node);
6898 _ = try addEnsureResult(&then_scope, then_result, then_node);6951 _ = try addEnsureResult(&then_scope, then_result, then_node);
68996952
6900 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);6953 try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
...@@ -6913,7 +6966,7 @@ fn forExpr(...@@ -6913,7 +6966,7 @@ fn forExpr(
6913 // control flow apply to outer loops; not this one.6966 // control flow apply to outer loops; not this one.
6914 loop_scope.continue_block = .none;6967 loop_scope.continue_block = .none;
6915 loop_scope.break_block = .none;6968 loop_scope.break_block = .none;
6916 const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_info, else_node);6969 const else_result = try fullBodyExpr(&else_scope, sub_scope, loop_scope.break_result_info, else_node);
6917 if (is_statement) {6970 if (is_statement) {
6918 _ = try addEnsureResult(&else_scope, else_result, else_node);6971 _ = try addEnsureResult(&else_scope, else_result, else_node);
6919 }6972 }
...@@ -7388,7 +7441,7 @@ fn switchExprErrUnion(...@@ -7388,7 +7441,7 @@ fn switchExprErrUnion(
7388 }7441 }
73897442
7390 const target_expr_node = case.ast.target_expr;7443 const target_expr_node = case.ast.target_expr;
7391 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);7444 const case_result = try fullBodyExpr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
7392 // check capture_scope, not err_scope to avoid false positive unused error capture7445 // check capture_scope, not err_scope to avoid false positive unused error capture
7393 try checkUsed(parent_gz, &case_scope.base, err_scope.parent);7446 try checkUsed(parent_gz, &case_scope.base, err_scope.parent);
7394 const uses_err = err_scope.used != 0 or err_scope.discarded != 0;7447 const uses_err = err_scope.used != 0 or err_scope.discarded != 0;
...@@ -7849,7 +7902,7 @@ fn switchExpr(...@@ -7849,7 +7902,7 @@ fn switchExpr(
7849 try case_scope.addDbgVar(.dbg_var_val, dbg_var_tag_name, dbg_var_tag_inst);7902 try case_scope.addDbgVar(.dbg_var_val, dbg_var_tag_name, dbg_var_tag_inst);
7850 }7903 }
7851 const target_expr_node = case.ast.target_expr;7904 const target_expr_node = case.ast.target_expr;
7852 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);7905 const case_result = try fullBodyExpr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
7853 try checkUsed(parent_gz, &case_scope.base, sub_scope);7906 try checkUsed(parent_gz, &case_scope.base, sub_scope);
7854 if (!parent_gz.refIsNoReturn(case_result)) {7907 if (!parent_gz.refIsNoReturn(case_result)) {
7855 _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node);7908 _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node);
...@@ -8405,7 +8458,14 @@ fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node:...@@ -8405,7 +8458,14 @@ fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node:
8405 try astgen.errNoteTok(num_token, "use '-0.0' for a floating-point signed zero", .{}),8458 try astgen.errNoteTok(num_token, "use '-0.0' for a floating-point signed zero", .{}),
8406 },8459 },
8407 ),8460 ),
8408 1 => .one,8461 1 => {
8462 // Handle the negation here!
8463 const result: Zir.Inst.Ref = switch (sign) {
8464 .positive => .one,
8465 .negative => .negative_one,
8466 };
8467 return rvalue(gz, ri, result, source_node);
8468 },
8409 else => try gz.addInt(num),8469 else => try gz.addInt(num),
8410 },8470 },
8411 .big_int => |base| big: {8471 .big_int => |base| big: {
...@@ -9752,7 +9812,7 @@ fn cImport(...@@ -9752,7 +9812,7 @@ fn cImport(
9752 defer block_scope.unstack();9812 defer block_scope.unstack();
97539813
9754 const block_inst = try gz.makeBlockInst(.c_import, node);9814 const block_inst = try gz.makeBlockInst(.c_import, node);
9755 const block_result = try expr(&block_scope, &block_scope.base, .{ .rl = .none }, body_node);9815 const block_result = try fullBodyExpr(&block_scope, &block_scope.base, .{ .rl = .none }, body_node);
9756 _ = try gz.addUnNode(.ensure_result_used, block_result, node);9816 _ = try gz.addUnNode(.ensure_result_used, block_result, node);
9757 if (!gz.refIsNoReturn(block_result)) {9817 if (!gz.refIsNoReturn(block_result)) {
9758 _ = try block_scope.addBreak(.break_inline, block_inst, .void_value);9818 _ = try block_scope.addBreak(.break_inline, block_inst, .void_value);
...@@ -9835,7 +9895,7 @@ fn callExpr(...@@ -9835,7 +9895,7 @@ fn callExpr(
9835 defer arg_block.unstack();9895 defer arg_block.unstack();
98369896
9837 // `call_inst` is reused to provide the param type.9897 // `call_inst` is reused to provide the param type.
9838 const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);9898 const arg_ref = try fullBodyExpr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);
9839 _ = try arg_block.addBreakWithSrcNode(.break_inline, call_index, arg_ref, param_node);9899 _ = try arg_block.addBreakWithSrcNode(.break_inline, call_index, arg_ref, param_node);
98409900
9841 const body = arg_block.instructionsSlice();9901 const body = arg_block.instructionsSlice();
...@@ -10871,10 +10931,11 @@ fn rvalueInner(...@@ -10871,10 +10931,11 @@ fn rvalueInner(
10871 .ty => |ty_inst| {10931 .ty => |ty_inst| {
10872 // Quickly eliminate some common, unnecessary type coercion.10932 // Quickly eliminate some common, unnecessary type coercion.
10873 const as_ty = @as(u64, @intFromEnum(Zir.Inst.Ref.type_type)) << 32;10933 const as_ty = @as(u64, @intFromEnum(Zir.Inst.Ref.type_type)) << 32;
10874 const as_comptime_int = @as(u64, @intFromEnum(Zir.Inst.Ref.comptime_int_type)) << 32;
10875 const as_bool = @as(u64, @intFromEnum(Zir.Inst.Ref.bool_type)) << 32;10934 const as_bool = @as(u64, @intFromEnum(Zir.Inst.Ref.bool_type)) << 32;
10876 const as_usize = @as(u64, @intFromEnum(Zir.Inst.Ref.usize_type)) << 32;
10877 const as_void = @as(u64, @intFromEnum(Zir.Inst.Ref.void_type)) << 32;10935 const as_void = @as(u64, @intFromEnum(Zir.Inst.Ref.void_type)) << 32;
10936 const as_comptime_int = @as(u64, @intFromEnum(Zir.Inst.Ref.comptime_int_type)) << 32;
10937 const as_usize = @as(u64, @intFromEnum(Zir.Inst.Ref.usize_type)) << 32;
10938 const as_u8 = @as(u64, @intFromEnum(Zir.Inst.Ref.u8_type)) << 32;
10878 switch ((@as(u64, @intFromEnum(ty_inst)) << 32) | @as(u64, @intFromEnum(result))) {10939 switch ((@as(u64, @intFromEnum(ty_inst)) << 32) | @as(u64, @intFromEnum(result))) {
10879 as_ty | @intFromEnum(Zir.Inst.Ref.u1_type),10940 as_ty | @intFromEnum(Zir.Inst.Ref.u1_type),
10880 as_ty | @intFromEnum(Zir.Inst.Ref.u8_type),10941 as_ty | @intFromEnum(Zir.Inst.Ref.u8_type),
...@@ -10939,13 +11000,30 @@ fn rvalueInner(...@@ -10939,13 +11000,30 @@ fn rvalueInner(
10939 as_ty | @intFromEnum(Zir.Inst.Ref.empty_struct_type),11000 as_ty | @intFromEnum(Zir.Inst.Ref.empty_struct_type),
10940 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero),11001 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero),
10941 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one),11002 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one),
10942 as_bool | @intFromEnum(Zir.Inst.Ref.bool_true),11003 as_comptime_int | @intFromEnum(Zir.Inst.Ref.negative_one),
10943 as_bool | @intFromEnum(Zir.Inst.Ref.bool_false),
10944 as_usize | @intFromEnum(Zir.Inst.Ref.zero_usize),11004 as_usize | @intFromEnum(Zir.Inst.Ref.zero_usize),
10945 as_usize | @intFromEnum(Zir.Inst.Ref.one_usize),11005 as_usize | @intFromEnum(Zir.Inst.Ref.one_usize),
11006 as_u8 | @intFromEnum(Zir.Inst.Ref.zero_u8),
11007 as_u8 | @intFromEnum(Zir.Inst.Ref.one_u8),
11008 as_u8 | @intFromEnum(Zir.Inst.Ref.four_u8),
11009 as_bool | @intFromEnum(Zir.Inst.Ref.bool_true),
11010 as_bool | @intFromEnum(Zir.Inst.Ref.bool_false),
10946 as_void | @intFromEnum(Zir.Inst.Ref.void_value),11011 as_void | @intFromEnum(Zir.Inst.Ref.void_value),
10947 => return result, // type of result is already correct11012 => return result, // type of result is already correct
1094811013
11014 as_usize | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_usize,
11015 as_u8 | @intFromEnum(Zir.Inst.Ref.zero) => return .zero_u8,
11016 as_usize | @intFromEnum(Zir.Inst.Ref.one) => return .one_usize,
11017 as_u8 | @intFromEnum(Zir.Inst.Ref.one) => return .one_u8,
11018 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero,
11019 as_u8 | @intFromEnum(Zir.Inst.Ref.zero_usize) => return .zero_u8,
11020 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one,
11021 as_u8 | @intFromEnum(Zir.Inst.Ref.one_usize) => return .one_u8,
11022 as_comptime_int | @intFromEnum(Zir.Inst.Ref.zero_u8) => return .zero,
11023 as_usize | @intFromEnum(Zir.Inst.Ref.zero_u8) => return .zero_usize,
11024 as_comptime_int | @intFromEnum(Zir.Inst.Ref.one_u8) => return .one,
11025 as_usize | @intFromEnum(Zir.Inst.Ref.one_u8) => return .one_usize,
11026
10949 // Need an explicit type coercion instruction.11027 // Need an explicit type coercion instruction.
10950 else => return gz.addPlNode(ri.zirTag(), src_node, Zir.Inst.As{11028 else => return gz.addPlNode(ri.zirTag(), src_node, Zir.Inst.As{
10951 .dest_type = ty_inst,11029 .dest_type = ty_inst,
...@@ -11676,7 +11754,8 @@ const GenZir = struct {...@@ -11676,7 +11754,8 @@ const GenZir = struct {
11676 /// Whether we're in an expression within a `@TypeOf` operand. In this case, closure of runtime11754 /// Whether we're in an expression within a `@TypeOf` operand. In this case, closure of runtime
11677 /// variables is permitted where it is usually not.11755 /// variables is permitted where it is usually not.
11678 is_typeof: bool = false,11756 is_typeof: bool = false,
11679 /// This is set to true for inline loops; false otherwise.11757 /// This is set to true for a `GenZir` of a `block_inline`, indicating that
11758 /// exits from this block should use `break_inline` rather than `break`.
11680 is_inline: bool = false,11759 is_inline: bool = false,
11681 c_import: bool = false,11760 c_import: bool = false,
11682 /// How decls created in this scope should be named.11761 /// How decls created in this scope should be named.
...@@ -13471,7 +13550,7 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {...@@ -13471,7 +13550,7 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {
1347113550
13472fn emitDbgStmt(gz: *GenZir, lc: LineColumn) !void {13551fn emitDbgStmt(gz: *GenZir, lc: LineColumn) !void {
13473 if (gz.is_comptime) return;13552 if (gz.is_comptime) return;
13474 if (gz.instructions.items.len > 0) {13553 if (gz.instructions.items.len > gz.instructions_top) {
13475 const astgen = gz.astgen;13554 const astgen = gz.astgen;
13476 const last = gz.instructions.items[gz.instructions.items.len - 1];13555 const last = gz.instructions.items[gz.instructions.items.len - 1];
13477 if (astgen.instructions.items(.tag)[@intFromEnum(last)] == .dbg_stmt) {13556 if (astgen.instructions.items(.tag)[@intFromEnum(last)] == .dbg_stmt) {
...@@ -13497,7 +13576,7 @@ fn emitDbgStmt(gz: *GenZir, lc: LineColumn) !void {...@@ -13497,7 +13576,7 @@ fn emitDbgStmt(gz: *GenZir, lc: LineColumn) !void {
13497/// instructions; fix up Sema so we don't need it!13576/// instructions; fix up Sema so we don't need it!
13498fn emitDbgStmtForceCurrentIndex(gz: *GenZir, lc: LineColumn) !void {13577fn emitDbgStmtForceCurrentIndex(gz: *GenZir, lc: LineColumn) !void {
13499 const astgen = gz.astgen;13578 const astgen = gz.astgen;
13500 if (gz.instructions.items.len > 0 and13579 if (gz.instructions.items.len > gz.instructions_top and
13501 @intFromEnum(gz.instructions.items[gz.instructions.items.len - 1]) == astgen.instructions.len - 1)13580 @intFromEnum(gz.instructions.items[gz.instructions.items.len - 1]) == astgen.instructions.len - 1)
13502 {13581 {
13503 const last = astgen.instructions.len - 1;13582 const last = astgen.instructions.len - 1;
src/Autodoc.zig+39-22
...@@ -5137,7 +5137,7 @@ fn analyzeFancyFunction(...@@ -5137,7 +5137,7 @@ fn analyzeFancyFunction(
5137 file,5137 file,
5138 scope,5138 scope,
5139 parent_src,5139 parent_src,
5140 fn_info.body[0],5140 fn_info.body,
5141 call_ctx,5141 call_ctx,
5142 );5142 );
5143 } else {5143 } else {
...@@ -5303,7 +5303,7 @@ fn analyzeFunction(...@@ -5303,7 +5303,7 @@ fn analyzeFunction(
5303 file,5303 file,
5304 scope,5304 scope,
5305 parent_src,5305 parent_src,
5306 fn_info.body[0],5306 fn_info.body,
5307 call_ctx,5307 call_ctx,
5308 );5308 );
5309 } else {5309 } else {
...@@ -5350,17 +5350,10 @@ fn getGenericReturnType(...@@ -5350,17 +5350,10 @@ fn getGenericReturnType(
5350 file: *File,5350 file: *File,
5351 scope: *Scope,5351 scope: *Scope,
5352 parent_src: SrcLocInfo, // function decl line5352 parent_src: SrcLocInfo, // function decl line
5353 body_main_block: Zir.Inst.Index,5353 body: []const Zir.Inst.Index,
5354 call_ctx: ?*const CallContext,5354 call_ctx: ?*const CallContext,
5355) !DocData.Expr {5355) !DocData.Expr {
5356 const tags = file.zir.instructions.items(.tag);5356 const tags = file.zir.instructions.items(.tag);
5357 const data = file.zir.instructions.items(.data);
5358
5359 // We expect `body_main_block` to be the first instruction
5360 // inside the function body, and for it to be a block instruction.
5361 const pl_node = data[@intFromEnum(body_main_block)].pl_node;
5362 const extra = file.zir.extraData(Zir.Inst.Block, pl_node.payload_index);
5363 const body = file.zir.bodySlice(extra.end, extra.data.body_len);
5364 if (body.len >= 4) {5357 if (body.len >= 4) {
5365 const maybe_ret_inst = body[body.len - 4];5358 const maybe_ret_inst = body[body.len - 4];
5366 switch (tags[@intFromEnum(maybe_ret_inst)]) {5359 switch (tags[@intFromEnum(maybe_ret_inst)]) {
...@@ -5676,6 +5669,42 @@ fn walkRef(...@@ -5676,6 +5669,42 @@ fn walkRef(
5676 .expr = .{ .int = .{ .value = 1 } },5669 .expr = .{ .int = .{ .value = 1 } },
5677 };5670 };
5678 },5671 },
5672 .negative_one => {
5673 return DocData.WalkResult{
5674 .typeRef = .{ .type = @intFromEnum(Ref.comptime_int_type) },
5675 .expr = .{ .int = .{ .value = 1, .negated = true } },
5676 };
5677 },
5678 .zero_usize => {
5679 return DocData.WalkResult{
5680 .typeRef = .{ .type = @intFromEnum(Ref.usize_type) },
5681 .expr = .{ .int = .{ .value = 0 } },
5682 };
5683 },
5684 .one_usize => {
5685 return DocData.WalkResult{
5686 .typeRef = .{ .type = @intFromEnum(Ref.usize_type) },
5687 .expr = .{ .int = .{ .value = 1 } },
5688 };
5689 },
5690 .zero_u8 => {
5691 return DocData.WalkResult{
5692 .typeRef = .{ .type = @intFromEnum(Ref.u8_type) },
5693 .expr = .{ .int = .{ .value = 0 } },
5694 };
5695 },
5696 .one_u8 => {
5697 return DocData.WalkResult{
5698 .typeRef = .{ .type = @intFromEnum(Ref.u8_type) },
5699 .expr = .{ .int = .{ .value = 1 } },
5700 };
5701 },
5702 .four_u8 => {
5703 return DocData.WalkResult{
5704 .typeRef = .{ .type = @intFromEnum(Ref.u8_type) },
5705 .expr = .{ .int = .{ .value = 4 } },
5706 };
5707 },
56795708
5680 .void_value => {5709 .void_value => {
5681 return DocData.WalkResult{5710 return DocData.WalkResult{
...@@ -5707,18 +5736,6 @@ fn walkRef(...@@ -5707,18 +5736,6 @@ fn walkRef(
5707 .empty_struct => {5736 .empty_struct => {
5708 return DocData.WalkResult{ .expr = .{ .@"struct" = &.{} } };5737 return DocData.WalkResult{ .expr = .{ .@"struct" = &.{} } };
5709 },5738 },
5710 .zero_usize => {
5711 return DocData.WalkResult{
5712 .typeRef = .{ .type = @intFromEnum(Ref.usize_type) },
5713 .expr = .{ .int = .{ .value = 0 } },
5714 };
5715 },
5716 .one_usize => {
5717 return DocData.WalkResult{
5718 .typeRef = .{ .type = @intFromEnum(Ref.usize_type) },
5719 .expr = .{ .int = .{ .value = 1 } },
5720 };
5721 },
5722 .calling_convention_type => {5739 .calling_convention_type => {
5723 return DocData.WalkResult{5740 return DocData.WalkResult{
5724 .typeRef = .{ .type = @intFromEnum(Ref.type_type) },5741 .typeRef = .{ .type = @intFromEnum(Ref.type_type) },
src/Module.zig+12-10
...@@ -3492,6 +3492,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -3492,6 +3492,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
3492 @panic("TODO: update owner Decl");3492 @panic("TODO: update owner Decl");
3493 }3493 }
34943494
3495 const decl_inst = decl.zir_decl_index.unwrap().?;
3496
3495 const gpa = mod.gpa;3497 const gpa = mod.gpa;
3496 const zir = decl.getFileScope(mod).zir;3498 const zir = decl.getFileScope(mod).zir;
34973499
...@@ -3563,7 +3565,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -3563,7 +3565,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
3563 try sema.declareDependency(.{ .src_hash = try ip.trackZir(3565 try sema.declareDependency(.{ .src_hash = try ip.trackZir(
3564 sema.gpa,3566 sema.gpa,
3565 decl.getFileScope(mod),3567 decl.getFileScope(mod),
3566 decl.zir_decl_index.unwrap().?,3568 decl_inst,
3567 ) });3569 ) });
35683570
3569 var block_scope: Sema.Block = .{3571 var block_scope: Sema.Block = .{
...@@ -3580,7 +3582,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -3580,7 +3582,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
35803582
3581 const decl_bodies = decl.zirBodies(mod);3583 const decl_bodies = decl.zirBodies(mod);
35823584
3583 const result_ref = (try sema.analyzeBodyBreak(&block_scope, decl_bodies.value_body)).?.operand;3585 const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst);
3584 // We'll do some other bits with the Sema. Clear the type target index just3586 // We'll do some other bits with the Sema. Clear the type target index just
3585 // in case they analyze any type.3587 // in case they analyze any type.
3586 sema.builtin_type_target_index = .none;3588 sema.builtin_type_target_index = .none;
...@@ -3593,7 +3595,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -3593,7 +3595,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
3593 const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 };3595 const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 };
3594 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 };3596 const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 };
3595 const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 };3597 const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 };
3596 const decl_tv = try sema.resolveInstValueAllowVariables(&block_scope, init_src, result_ref, .{3598 const decl_tv = try sema.resolveConstValueAllowVariables(&block_scope, init_src, result_ref, .{
3597 .needed_comptime_reason = "global variable initializer must be comptime-known",3599 .needed_comptime_reason = "global variable initializer must be comptime-known",
3598 });3600 });
35993601
...@@ -3709,13 +3711,13 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -3709,13 +3711,13 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
3709 decl.val = Value.fromInterned((try decl_tv.val.intern(decl_tv.ty, mod)));3711 decl.val = Value.fromInterned((try decl_tv.val.intern(decl_tv.ty, mod)));
3710 decl.alignment = blk: {3712 decl.alignment = blk: {
3711 const align_body = decl_bodies.align_body orelse break :blk .none;3713 const align_body = decl_bodies.align_body orelse break :blk .none;
3712 const align_ref = (try sema.analyzeBodyBreak(&block_scope, align_body)).?.operand;3714 const align_ref = try sema.resolveInlineBody(&block_scope, align_body, decl_inst);
3713 break :blk try sema.resolveAlign(&block_scope, align_src, align_ref);3715 break :blk try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
3714 };3716 };
3715 decl.@"linksection" = blk: {3717 decl.@"linksection" = blk: {
3716 const linksection_body = decl_bodies.linksection_body orelse break :blk .none;3718 const linksection_body = decl_bodies.linksection_body orelse break :blk .none;
3717 const linksection_ref = (try sema.analyzeBodyBreak(&block_scope, linksection_body)).?.operand;3719 const linksection_ref = try sema.resolveInlineBody(&block_scope, linksection_body, decl_inst);
3718 const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, .{3720 const bytes = try sema.toConstString(&block_scope, section_src, linksection_ref, .{
3719 .needed_comptime_reason = "linksection must be comptime-known",3721 .needed_comptime_reason = "linksection must be comptime-known",
3720 });3722 });
3721 if (mem.indexOfScalar(u8, bytes, 0) != null) {3723 if (mem.indexOfScalar(u8, bytes, 0) != null) {
...@@ -3741,8 +3743,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -3741,8 +3743,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
3741 .constant => target_util.defaultAddressSpace(target, .global_constant),3743 .constant => target_util.defaultAddressSpace(target, .global_constant),
3742 else => unreachable,3744 else => unreachable,
3743 };3745 };
3744 const addrspace_ref = (try sema.analyzeBodyBreak(&block_scope, addrspace_body)).?.operand;3746 const addrspace_ref = try sema.resolveInlineBody(&block_scope, addrspace_body, decl_inst);
3745 break :blk try sema.analyzeAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx);3747 break :blk try sema.analyzeAsAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx);
3746 };3748 };
3747 decl.has_tv = true;3749 decl.has_tv = true;
3748 decl.analysis = .complete;3750 decl.analysis = .complete;
...@@ -4513,7 +4515,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato...@@ -4513,7 +4515,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
4513 sema.error_return_trace_index_on_fn_entry = error_return_trace_index;4515 sema.error_return_trace_index_on_fn_entry = error_return_trace_index;
4514 inner_block.error_return_trace_index = error_return_trace_index;4516 inner_block.error_return_trace_index = error_return_trace_index;
45154517
4516 sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {4518 sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
4517 // TODO make these unreachable instead of @panic4519 // TODO make these unreachable instead of @panic
4518 error.NeededSourceLocation => @panic("zig compiler bug: NeededSourceLocation"),4520 error.NeededSourceLocation => @panic("zig compiler bug: NeededSourceLocation"),
4519 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),4521 error.GenericPoison => @panic("zig compiler bug: GenericPoison"),
src/Sema.zig+251-229
...@@ -876,104 +876,100 @@ pub fn deinit(sema: *Sema) void {...@@ -876,104 +876,100 @@ pub fn deinit(sema: *Sema) void {
876 sema.* = undefined;876 sema.* = undefined;
877}877}
878878
879/// Returns only the result from the body that is specified.879/// Performs semantic analysis of a ZIR body which is behind a runtime condition. If comptime
880/// Only appropriate to call when it is determined at comptime that this body880/// control flow happens here, Sema will convert it to runtime control flow by introducing post-hoc
881/// has no peers.881/// blocks where necessary.
882fn resolveBody(
883 sema: *Sema,
884 block: *Block,
885 body: []const Zir.Inst.Index,
886 /// This is the instruction that a break instruction within `body` can
887 /// use to return from the body.
888 body_inst: Zir.Inst.Index,
889) CompileError!Air.Inst.Ref {
890 const break_data = (try sema.analyzeBodyBreak(block, body)) orelse
891 return .unreachable_value;
892 // For comptime control flow, we need to detect when `analyzeBody` reports
893 // that we need to break from an outer block. In such case we
894 // use Zig's error mechanism to send control flow up the stack until
895 // we find the corresponding block to this break.
896 if (block.is_comptime and break_data.block_inst != body_inst) {
897 sema.comptime_break_inst = break_data.inst;
898 return error.ComptimeBreak;
899 }
900 return try sema.resolveInst(break_data.operand);
901}
902
903fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.Index) !void {882fn analyzeBodyRuntimeBreak(sema: *Sema, block: *Block, body: []const Zir.Inst.Index) !void {
904 _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {883 sema.analyzeBodyInner(block, body) catch |err| switch (err) {
905 error.ComptimeBreak => {884 error.ComptimeBreak => {
906 const zir_datas = sema.code.instructions.items(.data);885 const zir_datas = sema.code.instructions.items(.data);
907 const break_data = zir_datas[@intFromEnum(sema.comptime_break_inst)].@"break";886 const break_data = zir_datas[@intFromEnum(sema.comptime_break_inst)].@"break";
908 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;887 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
909 try sema.addRuntimeBreak(block, .{888 try sema.addRuntimeBreak(block, extra.block_inst, break_data.operand);
910 .block_inst = extra.block_inst,
911 .operand = break_data.operand,
912 .inst = sema.comptime_break_inst,
913 });
914 },889 },
915 else => |e| return e,890 else => |e| return e,
916 };891 };
917}892}
918893
919pub fn analyzeBody(894/// Semantically analyze a ZIR function body. It is guranteed by AstGen that such a body cannot
895/// trigger comptime control flow to move above the function body.
896pub fn analyzeFnBody(
920 sema: *Sema,897 sema: *Sema,
921 block: *Block,898 block: *Block,
922 body: []const Zir.Inst.Index,899 body: []const Zir.Inst.Index,
923) !void {900) !void {
924 _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {901 sema.analyzeBodyInner(block, body) catch |err| switch (err) {
925 error.ComptimeBreak => unreachable, // unexpected comptime control flow902 error.ComptimeBreak => unreachable, // unexpected comptime control flow
926 else => |e| return e,903 else => |e| return e,
927 };904 };
928}905}
929906
930const BreakData = struct {907/// Given a ZIR body which can be exited via a `break_inline` instruction, or a non-inline body which
931 block_inst: Zir.Inst.Index,908/// we are evaluating at comptime, semantically analyze the body and return the result from it.
932 operand: Zir.Inst.Ref,909/// Returns `null` if control flow did not break from this block, but instead terminated with some
933 inst: Zir.Inst.Index,910/// other runtime noreturn instruction. Compile-time breaks to blocks further up the stack still
934};911/// return `error.ComptimeBreak`. If `block.is_comptime`, this function will never return `null`.
935912fn analyzeInlineBody(
936pub fn analyzeBodyBreak(
937 sema: *Sema,913 sema: *Sema,
938 block: *Block,914 block: *Block,
939 body: []const Zir.Inst.Index,915 body: []const Zir.Inst.Index,
940) CompileError!?BreakData {916 /// The index which a break instruction can target to break from this body.
941 const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {917 break_target: Zir.Inst.Index,
942 error.ComptimeBreak => sema.comptime_break_inst,918) CompileError!?Air.Inst.Ref {
943 else => |e| return e,919 if (sema.analyzeBodyInner(block, body)) |_| {
944 };
945 if (block.instructions.items.len != 0 and
946 sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef()))
947 return null;920 return null;
921 } else |err| switch (err) {
922 error.ComptimeBreak => {},
923 else => |e| return e,
924 }
925 const break_inst = sema.comptime_break_inst;
948 const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break";926 const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break";
949 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;927 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
950 return BreakData{928 if (extra.block_inst != break_target) {
951 .block_inst = extra.block_inst,929 // This control flow goes further up the stack.
952 .operand = break_data.operand,930 return error.ComptimeBreak;
953 .inst = break_inst,931 }
954 };932 return try sema.resolveInst(break_data.operand);
955}933}
956934
957/// ZIR instructions which are always `noreturn` return this. This matches the935/// Like `analyzeInlineBody`, but if the body does not break with a value, returns
958/// return type of `analyzeBody` so that we can tail call them.936/// `.unreachable_value` instead of `null`. Notably, use this to evaluate an arbitrary
959/// Only appropriate to return when the instruction is known to be NoReturn937/// body at comptime to a single result value.
960/// solely based on the ZIR tag.938pub fn resolveInlineBody(
961const always_noreturn: CompileError!Zir.Inst.Index = @as(Zir.Inst.Index, undefined);939 sema: *Sema,
962940 block: *Block,
963/// This function is the main loop of `Sema` and it can be used in two different ways:941 body: []const Zir.Inst.Index,
964/// * The traditional way where there are N breaks out of the block and peer type942 /// The index which a break instruction can target to break from this body.
965/// resolution is done on the break operands. In this case, the `Zir.Inst.Index`943 break_target: Zir.Inst.Index,
966/// part of the return value will be `undefined`, and callsites should ignore it,944) CompileError!Air.Inst.Ref {
967/// finding the block result value via the block scope.945 return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
968/// * The "flat" way. There is only 1 break out of the block, and it is with a `break_inline`946}
969/// instruction. In this case, the `Zir.Inst.Index` part of the return value will be947
970/// the break instruction. This communicates both which block the break applies to, as948/// This function is the main loop of `Sema`. It analyzes a single body of ZIR instructions.
971/// well as the operand. No block scope needs to be created for this strategy.949///
950/// If this function returns normally, the merges of `block` were populated with all possible
951/// (runtime) results of this block. Peer type resolution should be performed on the result,
952/// and relevant runtime instructions written to perform necessary coercions and breaks. See
953/// `resolveAnalyzedBlock`. This form of return is impossible if `block.is_comptime == true`.
954///
955/// Alternatively, this function may return `error.ComptimeBreak`. This indicates that comptime
956/// control flow is happening, and we are breaking at comptime from a block indicated by the
957/// break instruction in `sema.comptime_break_inst`. This occurs for any `break_inline`, or for a
958/// standard `break` at comptime. This error is pushed up the stack until the target block is
959/// reached, at which point the break operand will be fetched.
960///
961/// It is rare to call this function directly. Usually, you want one of the following wrappers:
962/// * If the body is exited via a `break_inline`, or is being evaluated at comptime,
963/// use `Sema.analyzeInlineBody` or `Sema.resolveInlineBody`.
964/// * If the body is behind a fresh runtime condition, use `Sema.analyzeBodyRuntimeBreak`.
965/// * If the body is an entire function body, use `Sema.analyzeFnBody`.
966/// * If the body is to be generated into an AIR `block`, use `Sema.resolveBlockBody`.
967/// * Otherwise, direct usage of `Sema.analyzeBodyInner` may be necessary.
972fn analyzeBodyInner(968fn analyzeBodyInner(
973 sema: *Sema,969 sema: *Sema,
974 block: *Block,970 block: *Block,
975 body: []const Zir.Inst.Index,971 body: []const Zir.Inst.Index,
976) CompileError!Zir.Inst.Index {972) CompileError!void {
977 // No tracy calls here, to avoid interfering with the tail call mechanism.973 // No tracy calls here, to avoid interfering with the tail call mechanism.
978974
979 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);975 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);
...@@ -997,7 +993,7 @@ fn analyzeBodyInner(...@@ -997,7 +993,7 @@ fn analyzeBodyInner(
997 // the loop. The only way to break out of the loop is with a `noreturn`993 // the loop. The only way to break out of the loop is with a `noreturn`
998 // instruction.994 // instruction.
999 var i: u32 = 0;995 var i: u32 = 0;
1000 const result = while (true) {996 while (true) {
1001 crash_info.setBodyIndex(i);997 crash_info.setBodyIndex(i);
1002 const inst = body[i];998 const inst = body[i];
1003 std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{999 std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{
...@@ -1214,14 +1210,14 @@ fn analyzeBodyInner(...@@ -1214,14 +1210,14 @@ fn analyzeBodyInner(
1214 // Instructions that we know to *always* be noreturn based solely on their tag.1210 // Instructions that we know to *always* be noreturn based solely on their tag.
1215 // These functions match the return type of analyzeBody so that we can1211 // These functions match the return type of analyzeBody so that we can
1216 // tail call them here.1212 // tail call them here.
1217 .compile_error => break sema.zirCompileError(block, inst),1213 .compile_error => break try sema.zirCompileError(block, inst),
1218 .ret_implicit => break sema.zirRetImplicit(block, inst),1214 .ret_implicit => break try sema.zirRetImplicit(block, inst),
1219 .ret_node => break sema.zirRetNode(block, inst),1215 .ret_node => break try sema.zirRetNode(block, inst),
1220 .ret_load => break sema.zirRetLoad(block, inst),1216 .ret_load => break try sema.zirRetLoad(block, inst),
1221 .ret_err_value => break sema.zirRetErrValue(block, inst),1217 .ret_err_value => break try sema.zirRetErrValue(block, inst),
1222 .@"unreachable" => break sema.zirUnreachable(block, inst),1218 .@"unreachable" => break try sema.zirUnreachable(block, inst),
1223 .panic => break sema.zirPanic(block, inst),1219 .panic => break try sema.zirPanic(block, inst),
1224 .trap => break sema.zirTrap(block, inst),1220 .trap => break try sema.zirTrap(block, inst),
1225 // zig fmt: on1221 // zig fmt: on
12261222
1227 // This instruction never exists in an analyzed body. It exists only in the declaration1223 // This instruction never exists in an analyzed body. It exists only in the declaration
...@@ -1247,7 +1243,7 @@ fn analyzeBodyInner(...@@ -1247,7 +1243,7 @@ fn analyzeBodyInner(
1247 .builtin_extern => try sema.zirBuiltinExtern( block, extended),1243 .builtin_extern => try sema.zirBuiltinExtern( block, extended),
1248 .@"asm" => try sema.zirAsm( block, extended, false),1244 .@"asm" => try sema.zirAsm( block, extended, false),
1249 .asm_expr => try sema.zirAsm( block, extended, true),1245 .asm_expr => try sema.zirAsm( block, extended, true),
1250 .typeof_peer => try sema.zirTypeofPeer( block, extended),1246 .typeof_peer => try sema.zirTypeofPeer( block, extended, inst),
1251 .compile_log => try sema.zirCompileLog( extended),1247 .compile_log => try sema.zirCompileLog( extended),
1252 .min_multi => try sema.zirMinMaxMulti( block, extended, .min),1248 .min_multi => try sema.zirMinMaxMulti( block, extended, .min),
1253 .max_multi => try sema.zirMinMaxMulti( block, extended, .max),1249 .max_multi => try sema.zirMinMaxMulti( block, extended, .max),
...@@ -1522,18 +1518,16 @@ fn analyzeBodyInner(...@@ -1522,18 +1518,16 @@ fn analyzeBodyInner(
1522 // Special case instructions to handle comptime control flow.1518 // Special case instructions to handle comptime control flow.
1523 .@"break" => {1519 .@"break" => {
1524 if (block.is_comptime) {1520 if (block.is_comptime) {
1525 break inst; // same as break_inline1521 sema.comptime_break_inst = inst;
1522 return error.ComptimeBreak;
1526 } else {1523 } else {
1527 break sema.zirBreak(block, inst);1524 try sema.zirBreak(block, inst);
1525 break;
1528 }1526 }
1529 },1527 },
1530 .break_inline => {1528 .break_inline => {
1531 if (block.is_comptime) {1529 sema.comptime_break_inst = inst;
1532 break inst;1530 return error.ComptimeBreak;
1533 } else {
1534 sema.comptime_break_inst = inst;
1535 return error.ComptimeBreak;
1536 }
1537 },1531 },
1538 .repeat => {1532 .repeat => {
1539 if (block.is_comptime) {1533 if (block.is_comptime) {
...@@ -1548,7 +1542,10 @@ fn analyzeBodyInner(...@@ -1548,7 +1542,10 @@ fn analyzeBodyInner(
1548 i = 0;1542 i = 0;
1549 continue;1543 continue;
1550 } else {1544 } else {
1551 break always_noreturn;1545 // We are definitely called by `zirLoop`, which will treat the
1546 // fact that this body does not terminate `noreturn` as an
1547 // implicit repeat.
1548 break;
1552 }1549 }
1553 },1550 },
1554 .repeat_inline => {1551 .repeat_inline => {
...@@ -1584,13 +1581,8 @@ fn analyzeBodyInner(...@@ -1584,13 +1581,8 @@ fn analyzeBodyInner(
1584 child_block.instructions = block.instructions;1581 child_block.instructions = block.instructions;
1585 defer block.instructions = child_block.instructions;1582 defer block.instructions = child_block.instructions;
15861583
1587 const break_data = (try sema.analyzeBodyBreak(&child_block, inline_body)) orelse1584 const result = try sema.analyzeInlineBody(&child_block, inline_body, inst) orelse break;
1588 break always_noreturn;1585 break :blk result;
1589 if (inst == break_data.block_inst) {
1590 break :blk try sema.resolveInst(break_data.operand);
1591 } else {
1592 break break_data.inst;
1593 }
1594 },1586 },
1595 .block, .block_comptime => blk: {1587 .block, .block_comptime => blk: {
1596 if (!block.is_comptime) {1588 if (!block.is_comptime) {
...@@ -1615,13 +1607,8 @@ fn analyzeBodyInner(...@@ -1615,13 +1607,8 @@ fn analyzeBodyInner(
1615 child_block.instructions = block.instructions;1607 child_block.instructions = block.instructions;
1616 defer block.instructions = child_block.instructions;1608 defer block.instructions = child_block.instructions;
16171609
1618 const break_data = (try sema.analyzeBodyBreak(&child_block, inline_body)) orelse1610 const result = try sema.analyzeInlineBody(&child_block, inline_body, inst) orelse break;
1619 break always_noreturn;1611 break :blk result;
1620 if (inst == break_data.block_inst) {
1621 break :blk try sema.resolveInst(break_data.operand);
1622 } else {
1623 break break_data.inst;
1624 }
1625 },1612 },
1626 .block_inline => blk: {1613 .block_inline => blk: {
1627 // Directly analyze the block body without introducing a new block.1614 // Directly analyze the block body without introducing a new block.
...@@ -1634,7 +1621,12 @@ fn analyzeBodyInner(...@@ -1634,7 +1621,12 @@ fn analyzeBodyInner(
1634 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);1621 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
1635 const gpa = sema.gpa;1622 const gpa = sema.gpa;
16361623
1637 const opt_break_data, const need_debug_scope = b: {1624 const BreakResult = struct {
1625 block_inst: Zir.Inst.Index,
1626 operand: Zir.Inst.Ref,
1627 };
1628
1629 const opt_break_data: ?BreakResult, const need_debug_scope = b: {
1638 // Create a temporary child block so that this inline block is properly1630 // Create a temporary child block so that this inline block is properly
1639 // labeled for any .restore_err_ret_index instructions1631 // labeled for any .restore_err_ret_index instructions
1640 var child_block = block.makeSubBlock();1632 var child_block = block.makeSubBlock();
...@@ -1660,11 +1652,26 @@ fn analyzeBodyInner(...@@ -1660,11 +1652,26 @@ fn analyzeBodyInner(
1660 child_block.instructions = block.instructions;1652 child_block.instructions = block.instructions;
1661 defer block.instructions = child_block.instructions;1653 defer block.instructions = child_block.instructions;
16621654
1663 const result = try sema.analyzeBodyBreak(&child_block, inline_body);1655 const break_result: ?BreakResult = if (sema.analyzeBodyInner(&child_block, inline_body)) |_| r: {
1656 break :r null;
1657 } else |err| switch (err) {
1658 error.ComptimeBreak => brk_res: {
1659 const break_inst = sema.comptime_break_inst;
1660 const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break";
1661 const break_extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
1662 break :brk_res .{
1663 .block_inst = break_extra.block_inst,
1664 .operand = break_data.operand,
1665 };
1666 },
1667 else => |e| return e,
1668 };
1669
1664 if (need_debug_scope) {1670 if (need_debug_scope) {
1665 _ = try sema.ensurePostHoc(block, inst);1671 _ = try sema.ensurePostHoc(block, inst);
1666 }1672 }
1667 break :b .{ result, need_debug_scope };1673
1674 break :b .{ break_result, need_debug_scope };
1668 };1675 };
16691676
1670 // A runtime conditional branch that needs a post-hoc block to be1677 // A runtime conditional branch that needs a post-hoc block to be
...@@ -1686,13 +1693,13 @@ fn analyzeBodyInner(...@@ -1686,13 +1693,13 @@ fn analyzeBodyInner(
1686 // It may pass through our currently being analyzed block_inline or it1693 // It may pass through our currently being analyzed block_inline or it
1687 // may point directly to it. In the latter case, this modifies the1694 // may point directly to it. In the latter case, this modifies the
1688 // block that we looked up in the post_hoc_blocks map above.1695 // block that we looked up in the post_hoc_blocks map above.
1689 try sema.addRuntimeBreak(block, break_data);1696 try sema.addRuntimeBreak(block, break_data.block_inst, break_data.operand);
1690 }1697 }
16911698
1692 try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]);1699 try labeled_block.block.instructions.appendSlice(gpa, block.instructions.items[block_index..]);
1693 block.instructions.items.len = block_index;1700 block.instructions.items.len = block_index;
16941701
1695 const block_result = try sema.analyzeBlockBody(block, inst_data.src(), &labeled_block.block, &labeled_block.label.merges, need_debug_scope);1702 const block_result = try sema.resolveAnalyzedBlock(block, inst_data.src(), &labeled_block.block, &labeled_block.label.merges, need_debug_scope);
1696 {1703 {
1697 // Destroy the ad-hoc block entry so that it does not interfere with1704 // Destroy the ad-hoc block entry so that it does not interfere with
1698 // the next iteration of comptime control flow, if any.1705 // the next iteration of comptime control flow, if any.
...@@ -1703,15 +1710,19 @@ fn analyzeBodyInner(...@@ -1703,15 +1710,19 @@ fn analyzeBodyInner(
1703 break :blk block_result;1710 break :blk block_result;
1704 }1711 }
17051712
1706 const break_data = opt_break_data orelse break always_noreturn;1713 const break_data = opt_break_data orelse break;
1707 if (inst == break_data.block_inst) {1714 if (inst == break_data.block_inst) {
1708 break :blk try sema.resolveInst(break_data.operand);1715 break :blk try sema.resolveInst(break_data.operand);
1709 } else {1716 } else {
1710 break break_data.inst;1717 // `comptime_break_inst` preserved from `analyzeBodyInner` above.
1718 return error.ComptimeBreak;
1711 }1719 }
1712 },1720 },
1713 .condbr => blk: {1721 .condbr => blk: {
1714 if (!block.is_comptime) break sema.zirCondbr(block, inst);1722 if (!block.is_comptime) {
1723 try sema.zirCondbr(block, inst);
1724 break;
1725 }
1715 // Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/82201726 // Same as condbr_inline. TODO https://github.com/ziglang/zig/issues/8220
1716 const inst_data = datas[@intFromEnum(inst)].pl_node;1727 const inst_data = datas[@intFromEnum(inst)].pl_node;
1717 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };1728 const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node };
...@@ -1728,13 +1739,9 @@ fn analyzeBodyInner(...@@ -1728,13 +1739,9 @@ fn analyzeBodyInner(
1728 const inline_body = if (cond.val.toBool()) then_body else else_body;1739 const inline_body = if (cond.val.toBool()) then_body else else_body;
17291740
1730 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);1741 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
1731 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse1742
1732 break always_noreturn;1743 const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break;
1733 if (inst == break_data.block_inst) {1744 break :blk result;
1734 break :blk try sema.resolveInst(break_data.operand);
1735 } else {
1736 break break_data.inst;
1737 }
1738 },1745 },
1739 .condbr_inline => blk: {1746 .condbr_inline => blk: {
1740 const inst_data = datas[@intFromEnum(inst)].pl_node;1747 const inst_data = datas[@intFromEnum(inst)].pl_node;
...@@ -1754,13 +1761,9 @@ fn analyzeBodyInner(...@@ -1754,13 +1761,9 @@ fn analyzeBodyInner(
1754 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);1761 try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src);
1755 const old_runtime_index = block.runtime_index;1762 const old_runtime_index = block.runtime_index;
1756 defer block.runtime_index = old_runtime_index;1763 defer block.runtime_index = old_runtime_index;
1757 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse1764
1758 break always_noreturn;1765 const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break;
1759 if (inst == break_data.block_inst) {1766 break :blk result;
1760 break :blk try sema.resolveInst(break_data.operand);
1761 } else {
1762 break break_data.inst;
1763 }
1764 },1767 },
1765 .@"try" => blk: {1768 .@"try" => blk: {
1766 if (!block.is_comptime) break :blk try sema.zirTry(block, inst);1769 if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
...@@ -1785,13 +1788,8 @@ fn analyzeBodyInner(...@@ -1785,13 +1788,8 @@ fn analyzeBodyInner(
1785 if (is_non_err_val.toBool()) {1788 if (is_non_err_val.toBool()) {
1786 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);1789 break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false);
1787 }1790 }
1788 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse1791 const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break;
1789 break always_noreturn;1792 break :blk result;
1790 if (inst == break_data.block_inst) {
1791 break :blk try sema.resolveInst(break_data.operand);
1792 } else {
1793 break break_data.inst;
1794 }
1795 },1793 },
1796 .try_ptr => blk: {1794 .try_ptr => blk: {
1797 if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst);1795 if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst);
...@@ -1811,22 +1809,22 @@ fn analyzeBodyInner(...@@ -1811,22 +1809,22 @@ fn analyzeBodyInner(
1811 if (is_non_err_val.toBool()) {1809 if (is_non_err_val.toBool()) {
1812 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);1810 break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
1813 }1811 }
1814 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse1812 const result = try sema.analyzeInlineBody(block, inline_body, inst) orelse break;
1815 break always_noreturn;1813 break :blk result;
1816 if (inst == break_data.block_inst) {
1817 break :blk try sema.resolveInst(break_data.operand);
1818 } else {
1819 break break_data.inst;
1820 }
1821 },1814 },
1822 .@"defer" => blk: {1815 .@"defer" => blk: {
1823 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"defer";1816 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"defer";
1824 const defer_body = sema.code.bodySlice(inst_data.index, inst_data.len);1817 const defer_body = sema.code.bodySlice(inst_data.index, inst_data.len);
1825 const break_inst = sema.analyzeBodyInner(block, defer_body) catch |err| switch (err) {1818 if (sema.analyzeBodyInner(block, defer_body)) |_| {
1826 error.ComptimeBreak => sema.comptime_break_inst,1819 // The defer terminated noreturn - no more analysis needed.
1820 break;
1821 } else |err| switch (err) {
1822 error.ComptimeBreak => {},
1827 else => |e| return e,1823 else => |e| return e,
1828 };1824 }
1829 if (break_inst != defer_body[defer_body.len - 1]) break always_noreturn;1825 if (sema.comptime_break_inst != defer_body[defer_body.len - 1]) {
1826 return error.ComptimeBreak;
1827 }
1830 break :blk .void_value;1828 break :blk .void_value;
1831 },1829 },
1832 .defer_err_code => blk: {1830 .defer_err_code => blk: {
...@@ -1835,11 +1833,16 @@ fn analyzeBodyInner(...@@ -1835,11 +1833,16 @@ fn analyzeBodyInner(
1835 const defer_body = sema.code.bodySlice(extra.index, extra.len);1833 const defer_body = sema.code.bodySlice(extra.index, extra.len);
1836 const err_code = try sema.resolveInst(inst_data.err_code);1834 const err_code = try sema.resolveInst(inst_data.err_code);
1837 map.putAssumeCapacity(extra.remapped_err_code, err_code);1835 map.putAssumeCapacity(extra.remapped_err_code, err_code);
1838 const break_inst = sema.analyzeBodyInner(block, defer_body) catch |err| switch (err) {1836 if (sema.analyzeBodyInner(block, defer_body)) |_| {
1839 error.ComptimeBreak => sema.comptime_break_inst,1837 // The defer terminated noreturn - no more analysis needed.
1838 break;
1839 } else |err| switch (err) {
1840 error.ComptimeBreak => {},
1840 else => |e| return e,1841 else => |e| return e,
1841 };1842 }
1842 if (break_inst != defer_body[defer_body.len - 1]) break always_noreturn;1843 if (sema.comptime_break_inst != defer_body[defer_body.len - 1]) {
1844 return error.ComptimeBreak;
1845 }
1843 break :blk .void_value;1846 break :blk .void_value;
1844 },1847 },
1845 };1848 };
...@@ -1847,17 +1850,15 @@ fn analyzeBodyInner(...@@ -1847,17 +1850,15 @@ fn analyzeBodyInner(
1847 // We're going to assume that the body itself is noreturn, so let's ensure that now1850 // We're going to assume that the body itself is noreturn, so let's ensure that now
1848 assert(block.instructions.items.len > 0);1851 assert(block.instructions.items.len > 0);
1849 assert(sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef()));1852 assert(sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef()));
1850 break always_noreturn;1853 break;
1851 }1854 }
1852 map.putAssumeCapacity(inst, air_inst);1855 map.putAssumeCapacity(inst, air_inst);
1853 i += 1;1856 i += 1;
1854 };1857 }
18551858
1856 // We may have overwritten the capture scope due to a `repeat` instruction where1859 // We may have overwritten the capture scope due to a `repeat` instruction where
1857 // the body had a capture; restore it now.1860 // the body had a capture; restore it now.
1858 block.wip_capture_scope = parent_capture_scope;1861 block.wip_capture_scope = parent_capture_scope;
1859
1860 return result;
1861}1862}
18621863
1863pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {1864pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
...@@ -1894,7 +1895,7 @@ fn resolveConstBool(...@@ -1894,7 +1895,7 @@ fn resolveConstBool(
1894 return val.toBool();1895 return val.toBool();
1895}1896}
18961897
1897pub fn resolveConstString(1898fn resolveConstString(
1898 sema: *Sema,1899 sema: *Sema,
1899 block: *Block,1900 block: *Block,
1900 src: LazySrcLoc,1901 src: LazySrcLoc,
...@@ -1902,6 +1903,16 @@ pub fn resolveConstString(...@@ -1902,6 +1903,16 @@ pub fn resolveConstString(
1902 reason: NeededComptimeReason,1903 reason: NeededComptimeReason,
1903) ![]u8 {1904) ![]u8 {
1904 const air_inst = try sema.resolveInst(zir_ref);1905 const air_inst = try sema.resolveInst(zir_ref);
1906 return sema.toConstString(block, src, air_inst, reason);
1907}
1908
1909pub fn toConstString(
1910 sema: *Sema,
1911 block: *Block,
1912 src: LazySrcLoc,
1913 air_inst: Air.Inst.Ref,
1914 reason: NeededComptimeReason,
1915) ![]u8 {
1905 const wanted_type = Type.slice_const_u8;1916 const wanted_type = Type.slice_const_u8;
1906 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);1917 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1907 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);1918 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
...@@ -2193,9 +2204,8 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val...@@ -2193,9 +2204,8 @@ fn resolveValueAllowVariables(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Val
2193 return val;2204 return val;
2194}2205}
21952206
2196/// Returns a compile error if the value has tag `variable`. See `resolveInstValue` for2207/// Returns a compile error if the value has tag `variable`.
2197/// a function that does not.2208fn resolveInstConst(
2198pub fn resolveInstConst(
2199 sema: *Sema,2209 sema: *Sema,
2200 block: *Block,2210 block: *Block,
2201 src: LazySrcLoc,2211 src: LazySrcLoc,
...@@ -2211,15 +2221,13 @@ pub fn resolveInstConst(...@@ -2211,15 +2221,13 @@ pub fn resolveInstConst(
2211}2221}
22122222
2213/// Value Tag may be `undef` or `variable`.2223/// Value Tag may be `undef` or `variable`.
2214/// See `resolveInstConst` for an alternative.2224pub fn resolveConstValueAllowVariables(
2215pub fn resolveInstValueAllowVariables(
2216 sema: *Sema,2225 sema: *Sema,
2217 block: *Block,2226 block: *Block,
2218 src: LazySrcLoc,2227 src: LazySrcLoc,
2219 zir_ref: Zir.Inst.Ref,2228 air_ref: Air.Inst.Ref,
2220 reason: NeededComptimeReason,2229 reason: NeededComptimeReason,
2221) CompileError!TypedValue {2230) CompileError!TypedValue {
2222 const air_ref = try sema.resolveInst(zir_ref);
2223 const val = try sema.resolveValueAllowVariables(air_ref) orelse {2231 const val = try sema.resolveValueAllowVariables(air_ref) orelse {
2224 return sema.failWithNeededComptime(block, src, reason);2232 return sema.failWithNeededComptime(block, src, reason);
2225 };2233 };
...@@ -2616,7 +2624,7 @@ fn reparentOwnedErrorMsg(...@@ -2616,7 +2624,7 @@ fn reparentOwnedErrorMsg(
26162624
2617const align_ty = Type.u29;2625const align_ty = Type.u29;
26182626
2619fn analyzeAsAlign(2627pub fn analyzeAsAlign(
2620 sema: *Sema,2628 sema: *Sema,
2621 block: *Block,2629 block: *Block,
2622 src: LazySrcLoc,2630 src: LazySrcLoc,
...@@ -2654,7 +2662,7 @@ fn validateAlignAllowZero(...@@ -2654,7 +2662,7 @@ fn validateAlignAllowZero(
2654 return Alignment.fromNonzeroByteUnits(alignment);2662 return Alignment.fromNonzeroByteUnits(alignment);
2655}2663}
26562664
2657pub fn resolveAlign(2665fn resolveAlign(
2658 sema: *Sema,2666 sema: *Sema,
2659 block: *Block,2667 block: *Block,
2660 src: LazySrcLoc,2668 src: LazySrcLoc,
...@@ -3054,7 +3062,7 @@ fn zirEnumDecl(...@@ -3054,7 +3062,7 @@ fn zirEnumDecl(
3054 defer enum_block.instructions.deinit(sema.gpa);3062 defer enum_block.instructions.deinit(sema.gpa);
30553063
3056 if (body.len != 0) {3064 if (body.len != 0) {
3057 try sema.analyzeBody(&enum_block, body);3065 _ = try sema.analyzeInlineBody(&enum_block, body, inst);
3058 }3066 }
30593067
3060 if (tag_type_ref != .none) {3068 if (tag_type_ref != .none) {
...@@ -5597,7 +5605,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -5597,7 +5605,7 @@ fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
5597 return Air.internedToRef((try sema.mod.floatValue(Type.comptime_float, number)).toIntern());5605 return Air.internedToRef((try sema.mod.floatValue(Type.comptime_float, number)).toIntern());
5598}5606}
55995607
5600fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {5608fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5601 const tracy = trace(@src());5609 const tracy = trace(@src());
5602 defer tracy.end();5610 defer tracy.end();
56035611
...@@ -5650,7 +5658,7 @@ fn zirCompileLog(...@@ -5650,7 +5658,7 @@ fn zirCompileLog(
5650 return .void_value;5658 return .void_value;
5651}5659}
56525660
5653fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {5661fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5654 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;5662 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
5655 const src = inst_data.src();5663 const src = inst_data.src();
5656 const msg_inst = try sema.resolveInst(inst_data.operand);5664 const msg_inst = try sema.resolveInst(inst_data.operand);
...@@ -5663,16 +5671,14 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I...@@ -5663,16 +5671,14 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I
5663 return sema.fail(block, src, "encountered @panic at comptime", .{});5671 return sema.fail(block, src, "encountered @panic at comptime", .{});
5664 }5672 }
5665 try sema.panicWithMsg(block, src, coerced_msg, .@"@panic");5673 try sema.panicWithMsg(block, src, coerced_msg, .@"@panic");
5666 return always_noreturn;
5667}5674}
56685675
5669fn zirTrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {5676fn zirTrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
5670 const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node;5677 const src_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].node;
5671 const src = LazySrcLoc.nodeOffset(src_node);5678 const src = LazySrcLoc.nodeOffset(src_node);
5672 if (block.is_comptime)5679 if (block.is_comptime)
5673 return sema.fail(block, src, "encountered @trap at comptime", .{});5680 return sema.fail(block, src, "encountered @trap at comptime", .{});
5674 _ = try block.addNoOp(.trap);5681 _ = try block.addNoOp(.trap);
5675 return always_noreturn;
5676}5682}
56775683
5678fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5684fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -5726,7 +5732,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5726,7 +5732,8 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5726 var loop_block = child_block.makeSubBlock();5732 var loop_block = child_block.makeSubBlock();
5727 defer loop_block.instructions.deinit(gpa);5733 defer loop_block.instructions.deinit(gpa);
57285734
5729 try sema.analyzeBody(&loop_block, body);5735 // Use `analyzeBodyInner` directly to push any comptime control flow up the stack.
5736 try sema.analyzeBodyInner(&loop_block, body);
57305737
5731 const loop_block_len = loop_block.instructions.items.len;5738 const loop_block_len = loop_block.instructions.items.len;
5732 if (loop_block_len > 0 and sema.typeOf(loop_block.instructions.items[loop_block_len - 1].toRef()).isNoReturn(mod)) {5739 if (loop_block_len > 0 and sema.typeOf(loop_block.instructions.items[loop_block_len - 1].toRef()).isNoReturn(mod)) {
...@@ -5742,7 +5749,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5742,7 +5749,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5742 );5749 );
5743 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(loop_block.instructions.items));5750 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(loop_block.instructions.items));
5744 }5751 }
5745 return sema.analyzeBlockBody(parent_block, src, &child_block, merges, false);5752 return sema.resolveAnalyzedBlock(parent_block, src, &child_block, merges, false);
5746}5753}
57475754
5748fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5755fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -5785,8 +5792,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5785,8 +5792,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5785 };5792 };
5786 defer child_block.instructions.deinit(gpa);5793 defer child_block.instructions.deinit(gpa);
57875794
5788 // Ignore the result, all the relevant operations have written to c_import_buf already.5795 _ = try sema.analyzeInlineBody(&child_block, body, inst);
5789 _ = try sema.analyzeBodyBreak(&child_block, body);
57905796
5791 var c_import_res = comp.cImport(c_import_buf.items, parent_block.ownerModule()) catch |err|5797 var c_import_res = comp.cImport(c_import_buf.items, parent_block.ownerModule()) catch |err|
5792 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});5798 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
...@@ -5916,6 +5922,9 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_compt...@@ -5916,6 +5922,9 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index, force_compt
5916 return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);5922 return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
5917}5923}
59185924
5925/// Semantically analyze the given ZIR body, emitting any resulting runtime code into the AIR block
5926/// specified by `child_block` if necessary (and emitting this block into `parent_block`).
5927/// TODO: `merges` is known from `child_block`, remove this parameter.
5919fn resolveBlockBody(5928fn resolveBlockBody(
5920 sema: *Sema,5929 sema: *Sema,
5921 parent_block: *Block,5930 parent_block: *Block,
...@@ -5928,12 +5937,12 @@ fn resolveBlockBody(...@@ -5928,12 +5937,12 @@ fn resolveBlockBody(
5928 merges: *Block.Merges,5937 merges: *Block.Merges,
5929) CompileError!Air.Inst.Ref {5938) CompileError!Air.Inst.Ref {
5930 if (child_block.is_comptime) {5939 if (child_block.is_comptime) {
5931 return sema.resolveBody(child_block, body, body_inst);5940 return sema.resolveInlineBody(child_block, body, body_inst);
5932 } else {5941 } else {
5933 var need_debug_scope = false;5942 var need_debug_scope = false;
5934 child_block.need_debug_scope = &need_debug_scope;5943 child_block.need_debug_scope = &need_debug_scope;
5935 if (sema.analyzeBodyInner(child_block, body)) |_| {5944 if (sema.analyzeBodyInner(child_block, body)) |_| {
5936 return sema.analyzeBlockBody(parent_block, src, child_block, merges, need_debug_scope);5945 return sema.resolveAnalyzedBlock(parent_block, src, child_block, merges, need_debug_scope);
5937 } else |err| switch (err) {5946 } else |err| switch (err) {
5938 error.ComptimeBreak => {5947 error.ComptimeBreak => {
5939 // Comptime control flow is happening, however child_block may still contain5948 // Comptime control flow is happening, however child_block may still contain
...@@ -5970,7 +5979,12 @@ fn resolveBlockBody(...@@ -5970,7 +5979,12 @@ fn resolveBlockBody(
5970 }5979 }
5971}5980}
59725981
5973fn analyzeBlockBody(5982/// After a body corresponding to an AIR `block` has been analyzed, this function places them into
5983/// the block pointed at by `merges.block_inst` if necessary, or the block may be elided in favor of
5984/// inlining the instructions directly into the parent block. Either way, it considers all merges of
5985/// this block, and combines them appropriately using peer type resolution, returning the final
5986/// value of the block.
5987fn resolveAnalyzedBlock(
5974 sema: *Sema,5988 sema: *Sema,
5975 parent_block: *Block,5989 parent_block: *Block,
5976 src: LazySrcLoc,5990 src: LazySrcLoc,
...@@ -6360,7 +6374,7 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co...@@ -6360,7 +6374,7 @@ fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) Co
6360 });6374 });
6361}6375}
63626376
6363fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {6377fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError!void {
6364 const tracy = trace(@src());6378 const tracy = trace(@src());
6365 defer tracy.end();6379 defer tracy.end();
63666380
...@@ -6386,7 +6400,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6386,7 +6400,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
6386 block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop;6400 block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop;
6387 block.runtime_loop = start_block.runtime_loop;6401 block.runtime_loop = start_block.runtime_loop;
6388 }6402 }
6389 return inst;6403 return;
6390 }6404 }
6391 }6405 }
6392 block = block.parent.?;6406 block = block.parent.?;
...@@ -7096,7 +7110,7 @@ const CallArgsInfo = union(enum) {...@@ -7096,7 +7110,7 @@ const CallArgsInfo = union(enum) {
7096 // Give the arg its result type7110 // Give the arg its result type
7097 sema.inst_map.putAssumeCapacity(zir_call.call_inst, Air.internedToRef(param_ty.toIntern()));7111 sema.inst_map.putAssumeCapacity(zir_call.call_inst, Air.internedToRef(param_ty.toIntern()));
7098 // Resolve the arg!7112 // Resolve the arg!
7099 const uncoerced_arg = try sema.resolveBody(block, arg_body, zir_call.call_inst);7113 const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst);
71007114
7101 if (sema.typeOf(uncoerced_arg).zigTypeTag(mod) == .NoReturn) {7115 if (sema.typeOf(uncoerced_arg).zigTypeTag(mod) == .NoReturn) {
7102 // This terminates resolution of arguments. The caller should7116 // This terminates resolution of arguments. The caller should
...@@ -7539,7 +7553,7 @@ fn analyzeCall(...@@ -7539,7 +7553,7 @@ fn analyzeCall(
7539 // each of the parameters, resolving the return type and providing it to the child7553 // each of the parameters, resolving the return type and providing it to the child
7540 // `Sema` so that it can be used for the `ret_ptr` instruction.7554 // `Sema` so that it can be used for the `ret_ptr` instruction.
7541 const ret_ty_inst = if (fn_info.ret_ty_body.len != 0)7555 const ret_ty_inst = if (fn_info.ret_ty_body.len != 0)
7542 try sema.resolveBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst.resolve(ip))7556 try sema.resolveInlineBody(&child_block, fn_info.ret_ty_body, module_fn.zir_body_inst.resolve(ip))
7543 else7557 else
7544 try sema.resolveInst(fn_info.ret_ty_ref);7558 try sema.resolveInst(fn_info.ret_ty_ref);
7545 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };7559 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
...@@ -7608,11 +7622,11 @@ fn analyzeCall(...@@ -7608,11 +7622,11 @@ fn analyzeCall(
7608 }7622 }
76097623
7610 const result = result: {7624 const result = result: {
7611 sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {7625 sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
7612 error.ComptimeReturn => break :result inlining.comptime_result,7626 error.ComptimeReturn => break :result inlining.comptime_result,
7613 else => |e| return e,7627 else => |e| return e,
7614 };7628 };
7615 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges, false);7629 break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, merges, false);
7616 };7630 };
76177631
7618 if (!is_comptime_call and !block.is_typeof and7632 if (!is_comptime_call and !block.is_typeof and
...@@ -7791,7 +7805,7 @@ fn analyzeInlineCallArg(...@@ -7791,7 +7805,7 @@ fn analyzeInlineCallArg(
7791 const param_ty = param_ty: {7805 const param_ty = param_ty: {
7792 const raw_param_ty = func_ty_info.param_types.get(ip)[arg_i.*];7806 const raw_param_ty = func_ty_info.param_types.get(ip)[arg_i.*];
7793 if (raw_param_ty != .generic_poison_type) break :param_ty raw_param_ty;7807 if (raw_param_ty != .generic_poison_type) break :param_ty raw_param_ty;
7794 const param_ty_inst = try ics.callee().resolveBody(param_block, param_body, inst);7808 const param_ty_inst = try ics.callee().resolveInlineBody(param_block, param_body, inst);
7795 const param_ty = try ics.callee().analyzeAsType(param_block, param_src, param_ty_inst);7809 const param_ty = try ics.callee().analyzeAsType(param_block, param_src, param_ty_inst);
7796 break :param_ty param_ty.toIntern();7810 break :param_ty param_ty.toIntern();
7797 };7811 };
...@@ -8026,7 +8040,7 @@ fn instantiateGenericCall(...@@ -8026,7 +8040,7 @@ fn instantiateGenericCall(
8026 child_sema.generic_call_decl = prev_generic_call_decl;8040 child_sema.generic_call_decl = prev_generic_call_decl;
8027 }8041 }
80288042
8029 const param_ty_inst = try child_sema.resolveBody(&child_block, param_ty_body, param_inst);8043 const param_ty_inst = try child_sema.resolveInlineBody(&child_block, param_ty_body, param_inst);
8030 break :param_ty try child_sema.analyzeAsType(&child_block, param_data.src(), param_ty_inst);8044 break :param_ty try child_sema.analyzeAsType(&child_block, param_data.src(), param_ty_inst);
8031 },8045 },
8032 else => unreachable,8046 else => unreachable,
...@@ -8118,7 +8132,7 @@ fn instantiateGenericCall(...@@ -8118,7 +8132,7 @@ fn instantiateGenericCall(
81188132
8119 // We've already handled parameters, so don't resolve the whole body. Instead, just8133 // We've already handled parameters, so don't resolve the whole body. Instead, just
8120 // do the instructions after the params (i.e. the func itself).8134 // do the instructions after the params (i.e. the func itself).
8121 const new_func_inst = try child_sema.resolveBody(&child_block, fn_info.param_body[args_info.count()..], fn_info.param_body_inst);8135 const new_func_inst = try child_sema.resolveInlineBody(&child_block, fn_info.param_body[args_info.count()..], fn_info.param_body_inst);
8122 const callee_index = (child_sema.resolveConstDefinedValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable).toIntern();8136 const callee_index = (child_sema.resolveConstDefinedValue(&child_block, .unneeded, new_func_inst, undefined) catch unreachable).toIntern();
81238137
8124 const callee = mod.funcInfo(callee_index);8138 const callee = mod.funcInfo(callee_index);
...@@ -9176,7 +9190,7 @@ fn resolveGenericBody(...@@ -9176,7 +9190,7 @@ fn resolveGenericBody(
9176 sema.generic_call_decl = prev_generic_call_decl;9190 sema.generic_call_decl = prev_generic_call_decl;
9177 }9191 }
91789192
9179 const uncasted = sema.resolveBody(block, body, func_inst) catch |err| break :err err;9193 const uncasted = sema.resolveInlineBody(block, body, func_inst) catch |err| break :err err;
9180 const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err;9194 const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err;
9181 const val = sema.resolveConstDefinedValue(block, src, result, reason) catch |err| break :err err;9195 const val = sema.resolveConstDefinedValue(block, src, result, reason) catch |err| break :err err;
9182 return val;9196 return val;
...@@ -9810,7 +9824,7 @@ fn zirParam(...@@ -9810,7 +9824,7 @@ fn zirParam(
9810 sema.generic_call_decl = prev_generic_call_decl;9824 sema.generic_call_decl = prev_generic_call_decl;
9811 }9825 }
98129826
9813 if (sema.resolveBody(block, body, inst)) |param_ty_inst| {9827 if (sema.resolveInlineBody(block, body, inst)) |param_ty_inst| {
9814 if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| {9828 if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| {
9815 break :param_ty param_ty;9829 break :param_ty param_ty;
9816 } else |err| break :err err;9830 } else |err| break :err err;
...@@ -11494,6 +11508,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11494,6 +11508,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
11494 sub_block.runtime_loop = null;11508 sub_block.runtime_loop = null;
11495 sub_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(main_operand_src, mod);11509 sub_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(main_operand_src, mod);
11496 sub_block.runtime_index.increment();11510 sub_block.runtime_index.increment();
11511 sub_block.need_debug_scope = null; // this body is emitted regardless
11497 defer sub_block.instructions.deinit(gpa);11512 defer sub_block.instructions.deinit(gpa);
1149811513
11499 try sema.analyzeBodyRuntimeBreak(&sub_block, non_error_case.body);11514 try sema.analyzeBodyRuntimeBreak(&sub_block, non_error_case.body);
...@@ -11556,7 +11571,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11556,7 +11571,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
11556 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions));11571 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions));
11557 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items));11572 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items));
1155811573
11559 return sema.analyzeBlockBody(block, main_src, &child_block, merges, false);11574 return sema.resolveAnalyzedBlock(block, main_src, &child_block, merges, false);
11560}11575}
1156111576
11562fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_ref: bool) CompileError!Air.Inst.Ref {11577fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_ref: bool) CompileError!Air.Inst.Ref {
...@@ -12178,7 +12193,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r...@@ -12178,7 +12193,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
12178 false,12193 false,
12179 );12194 );
1218012195
12181 return sema.analyzeBlockBody(block, src, &child_block, merges, false);12196 return sema.resolveAnalyzedBlock(block, src, &child_block, merges, false);
12182}12197}
1218312198
12184const SpecialProng = struct {12199const SpecialProng = struct {
...@@ -12229,6 +12244,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12229,6 +12244,7 @@ fn analyzeSwitchRuntimeBlock(
12229 case_block.runtime_loop = null;12244 case_block.runtime_loop = null;
12230 case_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(operand_src, mod);12245 case_block.runtime_cond = mod.declPtr(child_block.src_decl).toSrcLoc(operand_src, mod);
12231 case_block.runtime_index.increment();12246 case_block.runtime_index.increment();
12247 case_block.need_debug_scope = null; // this body is emitted regardless
12232 defer case_block.instructions.deinit(gpa);12248 defer case_block.instructions.deinit(gpa);
1223312249
12234 var extra_index: usize = special.end;12250 var extra_index: usize = special.end;
...@@ -18602,7 +18618,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -18602,7 +18618,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
18602 };18618 };
18603 defer child_block.instructions.deinit(sema.gpa);18619 defer child_block.instructions.deinit(sema.gpa);
1860418620
18605 const operand = try sema.resolveBody(&child_block, body, inst);18621 const operand = try sema.resolveInlineBody(&child_block, body, inst);
18606 const operand_ty = sema.typeOf(operand);18622 const operand_ty = sema.typeOf(operand);
18607 if (operand_ty.isGenericPoison()) return error.GenericPoison;18623 if (operand_ty.isGenericPoison()) return error.GenericPoison;
18608 return Air.internedToRef(operand_ty.toIntern());18624 return Air.internedToRef(operand_ty.toIntern());
...@@ -18657,6 +18673,7 @@ fn zirTypeofPeer(...@@ -18657,6 +18673,7 @@ fn zirTypeofPeer(
18657 sema: *Sema,18673 sema: *Sema,
18658 block: *Block,18674 block: *Block,
18659 extended: Zir.Inst.Extended.InstData,18675 extended: Zir.Inst.Extended.InstData,
18676 inst: Zir.Inst.Index,
18660) CompileError!Air.Inst.Ref {18677) CompileError!Air.Inst.Ref {
18661 const tracy = trace(@src());18678 const tracy = trace(@src());
18662 defer tracy.end();18679 defer tracy.end();
...@@ -18681,7 +18698,7 @@ fn zirTypeofPeer(...@@ -18681,7 +18698,7 @@ fn zirTypeofPeer(
18681 };18698 };
18682 defer child_block.instructions.deinit(sema.gpa);18699 defer child_block.instructions.deinit(sema.gpa);
18683 // Ignore the result, we only care about the instructions in `args`.18700 // Ignore the result, we only care about the instructions in `args`.
18684 _ = try sema.analyzeBodyBreak(&child_block, body);18701 _ = try sema.analyzeInlineBody(&child_block, body, inst);
1868518702
18686 const args = sema.code.refSlice(extra.end, extended.small);18703 const args = sema.code.refSlice(extra.end, extended.small);
1868718704
...@@ -18748,7 +18765,7 @@ fn zirBoolBr(...@@ -18748,7 +18765,7 @@ fn zirBoolBr(
18748 // comptime-known left-hand side. No need for a block here; the result18765 // comptime-known left-hand side. No need for a block here; the result
18749 // is simply the rhs expression. Here we rely on there only being 118766 // is simply the rhs expression. Here we rely on there only being 1
18750 // break instruction (`break_inline`).18767 // break instruction (`break_inline`).
18751 const rhs_result = try sema.resolveBody(parent_block, body, inst);18768 const rhs_result = try sema.resolveInlineBody(parent_block, body, inst);
18752 if (sema.typeOf(rhs_result).isNoReturn(mod)) {18769 if (sema.typeOf(rhs_result).isNoReturn(mod)) {
18753 return rhs_result;18770 return rhs_result;
18754 }18771 }
...@@ -18782,7 +18799,7 @@ fn zirBoolBr(...@@ -18782,7 +18799,7 @@ fn zirBoolBr(
18782 const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false;18799 const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false;
18783 _ = try lhs_block.addBr(block_inst, lhs_result);18800 _ = try lhs_block.addBr(block_inst, lhs_result);
1878418801
18785 const rhs_result = try sema.resolveBody(rhs_block, body, inst);18802 const rhs_result = try sema.resolveInlineBody(rhs_block, body, inst);
18786 const rhs_noret = sema.typeOf(rhs_result).isNoReturn(mod);18803 const rhs_noret = sema.typeOf(rhs_result).isNoReturn(mod);
18787 const coerced_rhs_result = if (!rhs_noret) rhs: {18804 const coerced_rhs_result = if (!rhs_noret) rhs: {
18788 const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src);18805 const coerced_result = try sema.coerce(rhs_block, Type.bool, rhs_result, rhs_src);
...@@ -18933,7 +18950,7 @@ fn zirCondbr(...@@ -18933,7 +18950,7 @@ fn zirCondbr(
18933 sema: *Sema,18950 sema: *Sema,
18934 parent_block: *Block,18951 parent_block: *Block,
18935 inst: Zir.Inst.Index,18952 inst: Zir.Inst.Index,
18936) CompileError!Zir.Inst.Index {18953) CompileError!void {
18937 const tracy = trace(@src());18954 const tracy = trace(@src());
18938 defer tracy.end();18955 defer tracy.end();
1893918956
...@@ -18952,8 +18969,7 @@ fn zirCondbr(...@@ -18952,8 +18969,7 @@ fn zirCondbr(
18952 const body = if (cond_val.toBool()) then_body else else_body;18969 const body = if (cond_val.toBool()) then_body else else_body;
1895318970
18954 try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src);18971 try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src);
18955 // We use `analyzeBodyInner` since we want to propagate any possible18972 // We use `analyzeBodyInner` since we want to propagate any comptime control flow to the caller.
18956 // `error.ComptimeBreak` to the caller.
18957 return sema.analyzeBodyInner(parent_block, body);18973 return sema.analyzeBodyInner(parent_block, body);
18958 }18974 }
1895918975
...@@ -18965,6 +18981,7 @@ fn zirCondbr(...@@ -18965,6 +18981,7 @@ fn zirCondbr(
18965 sub_block.runtime_loop = null;18981 sub_block.runtime_loop = null;
18966 sub_block.runtime_cond = mod.declPtr(parent_block.src_decl).toSrcLoc(cond_src, mod);18982 sub_block.runtime_cond = mod.declPtr(parent_block.src_decl).toSrcLoc(cond_src, mod);
18967 sub_block.runtime_index.increment();18983 sub_block.runtime_index.increment();
18984 sub_block.need_debug_scope = null; // this body is emitted regardless
18968 defer sub_block.instructions.deinit(gpa);18985 defer sub_block.instructions.deinit(gpa);
1896918986
18970 try sema.analyzeBodyRuntimeBreak(&sub_block, then_body);18987 try sema.analyzeBodyRuntimeBreak(&sub_block, then_body);
...@@ -19002,7 +19019,6 @@ fn zirCondbr(...@@ -19002,7 +19019,6 @@ fn zirCondbr(
19002 });19019 });
19003 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions));19020 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(true_instructions));
19004 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items));19021 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items));
19005 return always_noreturn;
19006}19022}
1900719023
19008fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19024fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -19027,14 +19043,15 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -19027,14 +19043,15 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
19027 }19043 }
19028 // We can analyze the body directly in the parent block because we know there are19044 // We can analyze the body directly in the parent block because we know there are
19029 // no breaks from the body possible, and that the body is noreturn.19045 // no breaks from the body possible, and that the body is noreturn.
19030 return sema.resolveBody(parent_block, body, inst);19046 try sema.analyzeBodyInner(parent_block, body);
19047 return .unreachable_value;
19031 }19048 }
1903219049
19033 var sub_block = parent_block.makeSubBlock();19050 var sub_block = parent_block.makeSubBlock();
19034 defer sub_block.instructions.deinit(sema.gpa);19051 defer sub_block.instructions.deinit(sema.gpa);
1903519052
19036 // This body is guaranteed to end with noreturn and has no breaks.19053 // This body is guaranteed to end with noreturn and has no breaks.
19037 _ = try sema.analyzeBodyInner(&sub_block, body);19054 try sema.analyzeBodyInner(&sub_block, body);
1903819055
19039 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).Struct.fields.len +19056 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).Struct.fields.len +
19040 sub_block.instructions.items.len);19057 sub_block.instructions.items.len);
...@@ -19074,14 +19091,15 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -19074,14 +19091,15 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
19074 }19091 }
19075 // We can analyze the body directly in the parent block because we know there are19092 // We can analyze the body directly in the parent block because we know there are
19076 // no breaks from the body possible, and that the body is noreturn.19093 // no breaks from the body possible, and that the body is noreturn.
19077 return sema.resolveBody(parent_block, body, inst);19094 try sema.analyzeBodyInner(parent_block, body);
19095 return .unreachable_value;
19078 }19096 }
1907919097
19080 var sub_block = parent_block.makeSubBlock();19098 var sub_block = parent_block.makeSubBlock();
19081 defer sub_block.instructions.deinit(sema.gpa);19099 defer sub_block.instructions.deinit(sema.gpa);
1908219100
19083 // This body is guaranteed to end with noreturn and has no breaks.19101 // This body is guaranteed to end with noreturn and has no breaks.
19084 _ = try sema.analyzeBodyInner(&sub_block, body);19102 try sema.analyzeBodyInner(&sub_block, body);
1908519103
19086 const operand_ty = sema.typeOf(operand);19104 const operand_ty = sema.typeOf(operand);
19087 const ptr_info = operand_ty.ptrInfo(mod);19105 const ptr_info = operand_ty.ptrInfo(mod);
...@@ -19156,13 +19174,13 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label...@@ -19156,13 +19174,13 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
19156 return labeled_block;19174 return labeled_block;
19157}19175}
1915819176
19159// A `break` statement is inside a runtime condition, but trying to19177/// A `break` statement is inside a runtime condition, but trying to
19160// break from an inline loop. In such case we must convert it to19178/// break from an inline loop. In such case we must convert it to
19161// a runtime break.19179/// a runtime break.
19162fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !void {19180fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, break_operand: Zir.Inst.Ref) !void {
19163 const labeled_block = try sema.ensurePostHoc(child_block, break_data.block_inst);19181 const labeled_block = try sema.ensurePostHoc(child_block, block_inst);
1916419182
19165 const operand = try sema.resolveInst(break_data.operand);19183 const operand = try sema.resolveInst(break_operand);
19166 const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand);19184 const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand);
1916719185
19168 try labeled_block.label.merges.results.append(sema.gpa, operand);19186 try labeled_block.label.merges.results.append(sema.gpa, operand);
...@@ -19176,7 +19194,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi...@@ -19176,7 +19194,7 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi
19176 }19194 }
19177}19195}
1917819196
19179fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {19197fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
19180 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable";19198 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"unreachable";
19181 const src = inst_data.src();19199 const src = inst_data.src();
1918219200
...@@ -19193,14 +19211,13 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -19193,14 +19211,13 @@ fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
19193 },19211 },
19194 else => |e| return e,19212 else => |e| return e,
19195 };19213 };
19196 return always_noreturn;
19197}19214}
1919819215
19199fn zirRetErrValue(19216fn zirRetErrValue(
19200 sema: *Sema,19217 sema: *Sema,
19201 block: *Block,19218 block: *Block,
19202 inst: Zir.Inst.Index,19219 inst: Zir.Inst.Index,
19203) CompileError!Zir.Inst.Index {19220) CompileError!void {
19204 const mod = sema.mod;19221 const mod = sema.mod;
19205 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;19222 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
19206 const err_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));19223 const err_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
...@@ -19219,7 +19236,7 @@ fn zirRetImplicit(...@@ -19219,7 +19236,7 @@ fn zirRetImplicit(
19219 sema: *Sema,19236 sema: *Sema,
19220 block: *Block,19237 block: *Block,
19221 inst: Zir.Inst.Index,19238 inst: Zir.Inst.Index,
19222) CompileError!Zir.Inst.Index {19239) CompileError!void {
19223 const tracy = trace(@src());19240 const tracy = trace(@src());
19224 defer tracy.end();19241 defer tracy.end();
1922519242
...@@ -19234,7 +19251,7 @@ fn zirRetImplicit(...@@ -19234,7 +19251,7 @@ fn zirRetImplicit(
19234 } else {19251 } else {
19235 try block.addUnreachable(r_brace_src, false);19252 try block.addUnreachable(r_brace_src, false);
19236 }19253 }
19237 return always_noreturn;19254 return;
19238 }19255 }
1923919256
19240 const operand = try sema.resolveInst(inst_data.operand);19257 const operand = try sema.resolveInst(inst_data.operand);
...@@ -19265,7 +19282,7 @@ fn zirRetImplicit(...@@ -19265,7 +19282,7 @@ fn zirRetImplicit(
19265 return sema.analyzeRet(block, operand, r_brace_src, r_brace_src);19282 return sema.analyzeRet(block, operand, r_brace_src, r_brace_src);
19266}19283}
1926719284
19268fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {19285fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
19269 const tracy = trace(@src());19286 const tracy = trace(@src());
19270 defer tracy.end();19287 defer tracy.end();
1927119288
...@@ -19276,7 +19293,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir...@@ -19276,7 +19293,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
19276 return sema.analyzeRet(block, operand, src, .{ .node_offset_return_operand = inst_data.src_node });19293 return sema.analyzeRet(block, operand, src, .{ .node_offset_return_operand = inst_data.src_node });
19277}19294}
1927819295
19279fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {19296fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
19280 const tracy = trace(@src());19297 const tracy = trace(@src());
19281 defer tracy.end();19298 defer tracy.end();
1928219299
...@@ -19295,7 +19312,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir...@@ -19295,7 +19312,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
19295 }19312 }
1929619313
19297 _ = try block.addUnOp(.ret_load, ret_ptr);19314 _ = try block.addUnOp(.ret_load, ret_ptr);
19298 return always_noreturn;
19299}19315}
1930019316
19301fn retWithErrTracing(19317fn retWithErrTracing(
...@@ -19305,12 +19321,12 @@ fn retWithErrTracing(...@@ -19305,12 +19321,12 @@ fn retWithErrTracing(
19305 is_non_err: Air.Inst.Ref,19321 is_non_err: Air.Inst.Ref,
19306 ret_tag: Air.Inst.Tag,19322 ret_tag: Air.Inst.Tag,
19307 operand: Air.Inst.Ref,19323 operand: Air.Inst.Ref,
19308) CompileError!Zir.Inst.Index {19324) CompileError!void {
19309 const mod = sema.mod;19325 const mod = sema.mod;
19310 const need_check = switch (is_non_err) {19326 const need_check = switch (is_non_err) {
19311 .bool_true => {19327 .bool_true => {
19312 _ = try block.addUnOp(ret_tag, operand);19328 _ = try block.addUnOp(ret_tag, operand);
19313 return always_noreturn;19329 return;
19314 },19330 },
19315 .bool_false => false,19331 .bool_false => false,
19316 else => true,19332 else => true,
...@@ -19326,7 +19342,7 @@ fn retWithErrTracing(...@@ -19326,7 +19342,7 @@ fn retWithErrTracing(
19326 if (!need_check) {19342 if (!need_check) {
19327 try sema.callBuiltin(block, src, return_err_fn, .never_inline, &args, .@"error return");19343 try sema.callBuiltin(block, src, return_err_fn, .never_inline, &args, .@"error return");
19328 _ = try block.addUnOp(ret_tag, operand);19344 _ = try block.addUnOp(ret_tag, operand);
19329 return always_noreturn;19345 return;
19330 }19346 }
1933119347
19332 var then_block = block.makeSubBlock();19348 var then_block = block.makeSubBlock();
...@@ -19353,8 +19369,6 @@ fn retWithErrTracing(...@@ -19353,8 +19369,6 @@ fn retWithErrTracing(
19353 .operand = is_non_err,19369 .operand = is_non_err,
19354 .payload = cond_br_payload,19370 .payload = cond_br_payload,
19355 } } });19371 } } });
19356
19357 return always_noreturn;
19358}19372}
1935919373
19360fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {19374fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
...@@ -19481,7 +19495,7 @@ fn analyzeRet(...@@ -19481,7 +19495,7 @@ fn analyzeRet(
19481 uncasted_operand: Air.Inst.Ref,19495 uncasted_operand: Air.Inst.Ref,
19482 src: LazySrcLoc,19496 src: LazySrcLoc,
19483 operand_src: LazySrcLoc,19497 operand_src: LazySrcLoc,
19484) CompileError!Zir.Inst.Index {19498) CompileError!void {
19485 // Special case for returning an error to an inferred error set; we need to19499 // Special case for returning an error to an inferred error set; we need to
19486 // add the error tag to the inferred error set of the in-scope function, so19500 // add the error tag to the inferred error set of the in-scope function, so
19487 // that the coercion below works correctly.19501 // that the coercion below works correctly.
...@@ -19513,7 +19527,7 @@ fn analyzeRet(...@@ -19513,7 +19527,7 @@ fn analyzeRet(
19513 try inlining.merges.results.append(sema.gpa, operand);19527 try inlining.merges.results.append(sema.gpa, operand);
19514 try inlining.merges.br_list.append(sema.gpa, br_inst.toIndex().?);19528 try inlining.merges.br_list.append(sema.gpa, br_inst.toIndex().?);
19515 try inlining.merges.src_locs.append(sema.gpa, operand_src);19529 try inlining.merges.src_locs.append(sema.gpa, operand_src);
19516 return always_noreturn;19530 return;
19517 } else if (block.is_comptime) {19531 } else if (block.is_comptime) {
19518 return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{});19532 return sema.fail(block, src, "function called at runtime cannot return value at comptime", .{});
19519 } else if (sema.func_is_naked) {19533 } else if (sema.func_is_naked) {
...@@ -19538,8 +19552,6 @@ fn analyzeRet(...@@ -19538,8 +19552,6 @@ fn analyzeRet(
19538 }19552 }
1953919553
19540 _ = try block.addUnOp(air_tag, operand);19554 _ = try block.addUnOp(air_tag, operand);
19541
19542 return always_noreturn;
19543}19555}
1954419556
19545fn floatOpAllowed(tag: Zir.Inst.Tag) bool {19557fn floatOpAllowed(tag: Zir.Inst.Tag) bool {
...@@ -19616,7 +19628,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19616,7 +19628,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19616 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {19628 const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: {
19617 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);19629 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
19618 extra_i += 1;19630 extra_i += 1;
19619 break :blk try sema.analyzeAddressSpace(block, addrspace_src, ref, .pointer);19631 break :blk try sema.resolveAddressSpace(block, addrspace_src, ref, .pointer);
19620 } else if (elem_ty.zigTypeTag(mod) == .Fn and target.cpu.arch == .avr) .flash else .generic;19632 } else if (elem_ty.zigTypeTag(mod) == .Fn and target.cpu.arch == .avr) .flash else .generic;
1962119633
19622 const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: {19634 const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: {
...@@ -35737,7 +35749,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp...@@ -35737,7 +35749,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.Key.StructType) Comp
35737 break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref);35749 break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref);
35738 } else {35750 } else {
35739 const body = zir.bodySlice(extra_index, backing_int_body_len);35751 const body = zir.bodySlice(extra_index, backing_int_body_len);
35740 const ty_ref = try sema.resolveBody(&block, body, zir_index);35752 const ty_ref = try sema.resolveInlineBody(&block, body, zir_index);
35741 break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref);35753 break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref);
35742 }35754 }
35743 };35755 };
...@@ -36618,7 +36630,7 @@ fn semaStructFields(...@@ -36618,7 +36630,7 @@ fn semaStructFields(
36618 assert(zir_field.type_body_len != 0);36630 assert(zir_field.type_body_len != 0);
36619 const body = zir.bodySlice(extra_index, zir_field.type_body_len);36631 const body = zir.bodySlice(extra_index, zir_field.type_body_len);
36620 extra_index += body.len;36632 extra_index += body.len;
36621 const ty_ref = try sema.resolveBody(&block_scope, body, zir_index);36633 const ty_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
36622 break :ty sema.analyzeAsType(&block_scope, .unneeded, ty_ref) catch |err| switch (err) {36634 break :ty sema.analyzeAsType(&block_scope, .unneeded, ty_ref) catch |err| switch (err) {
36623 error.NeededSourceLocation => {36635 error.NeededSourceLocation => {
36624 const ty_src = mod.fieldSrcLoc(decl_index, .{36636 const ty_src = mod.fieldSrcLoc(decl_index, .{
...@@ -36704,7 +36716,7 @@ fn semaStructFields(...@@ -36704,7 +36716,7 @@ fn semaStructFields(
36704 if (zir_field.align_body_len > 0) {36716 if (zir_field.align_body_len > 0) {
36705 const body = zir.bodySlice(extra_index, zir_field.align_body_len);36717 const body = zir.bodySlice(extra_index, zir_field.align_body_len);
36706 extra_index += body.len;36718 extra_index += body.len;
36707 const align_ref = try sema.resolveBody(&block_scope, body, zir_index);36719 const align_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
36708 const field_align = sema.analyzeAsAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) {36720 const field_align = sema.analyzeAsAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) {
36709 error.NeededSourceLocation => {36721 error.NeededSourceLocation => {
36710 const align_src = mod.fieldSrcLoc(decl_index, .{36722 const align_src = mod.fieldSrcLoc(decl_index, .{
...@@ -36854,7 +36866,7 @@ fn semaStructFieldInits(...@@ -36854,7 +36866,7 @@ fn semaStructFieldInits(
36854 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index});36866 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index});
36855 sema.inst_map.putAssumeCapacity(zir_index, type_ref);36867 sema.inst_map.putAssumeCapacity(zir_index, type_ref);
3685636868
36857 const init = try sema.resolveBody(&block_scope, body, zir_index);36869 const init = try sema.resolveInlineBody(&block_scope, body, zir_index);
36858 const coerced = sema.coerce(&block_scope, field_ty, init, .unneeded) catch |err| switch (err) {36870 const coerced = sema.coerce(&block_scope, field_ty, init, .unneeded) catch |err| switch (err) {
36859 error.NeededSourceLocation => {36871 error.NeededSourceLocation => {
36860 const init_src = mod.fieldSrcLoc(decl_index, .{36872 const init_src = mod.fieldSrcLoc(decl_index, .{
...@@ -36971,7 +36983,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un...@@ -36971,7 +36983,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
36971 defer assert(block_scope.instructions.items.len == 0);36983 defer assert(block_scope.instructions.items.len == 0);
3697236984
36973 if (body.len != 0) {36985 if (body.len != 0) {
36974 try sema.analyzeBody(&block_scope, body);36986 _ = try sema.analyzeInlineBody(&block_scope, body, zir_index);
36975 }36987 }
3697636988
36977 for (comptime_mutable_decls.items) |ct_decl_index| {36989 for (comptime_mutable_decls.items) |ct_decl_index| {
...@@ -37914,15 +37926,25 @@ pub const AddressSpaceContext = enum {...@@ -37914,15 +37926,25 @@ pub const AddressSpaceContext = enum {
37914 pointer,37926 pointer,
37915};37927};
3791637928
37917pub fn analyzeAddressSpace(37929fn resolveAddressSpace(
37918 sema: *Sema,37930 sema: *Sema,
37919 block: *Block,37931 block: *Block,
37920 src: LazySrcLoc,37932 src: LazySrcLoc,
37921 zir_ref: Zir.Inst.Ref,37933 zir_ref: Zir.Inst.Ref,
37922 ctx: AddressSpaceContext,37934 ctx: AddressSpaceContext,
37923) !std.builtin.AddressSpace {37935) !std.builtin.AddressSpace {
37924 const mod = sema.mod;
37925 const air_ref = try sema.resolveInst(zir_ref);37936 const air_ref = try sema.resolveInst(zir_ref);
37937 return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);
37938}
37939
37940pub fn analyzeAsAddressSpace(
37941 sema: *Sema,
37942 block: *Block,
37943 src: LazySrcLoc,
37944 air_ref: Air.Inst.Ref,
37945 ctx: AddressSpaceContext,
37946) !std.builtin.AddressSpace {
37947 const mod = sema.mod;
37926 const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src);37948 const coerced = try sema.coerce(block, Type.fromInterned(.address_space_type), air_ref, src);
37927 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{37949 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{
37928 .needed_comptime_reason = "address space must be comptime-known",37950 .needed_comptime_reason = "address space must be comptime-known",
src/codegen/llvm.zig+6-6
...@@ -5903,10 +5903,10 @@ pub const FuncGen = struct {...@@ -5903,10 +5903,10 @@ pub const FuncGen = struct {
5903 _ = try self.wip.brCond(cond, then_block, else_block);5903 _ = try self.wip.brCond(cond, then_block, else_block);
59045904
5905 self.wip.cursor = .{ .block = then_block };5905 self.wip.cursor = .{ .block = then_block };
5906 try self.genBody(then_body);5906 try self.genBodyDebugScope(then_body);
59075907
5908 self.wip.cursor = .{ .block = else_block };5908 self.wip.cursor = .{ .block = else_block };
5909 try self.genBody(else_body);5909 try self.genBodyDebugScope(else_body);
59105910
5911 // No need to reset the insert cursor since this instruction is noreturn.5911 // No need to reset the insert cursor since this instruction is noreturn.
5912 return .none;5912 return .none;
...@@ -5987,7 +5987,7 @@ pub const FuncGen = struct {...@@ -5987,7 +5987,7 @@ pub const FuncGen = struct {
5987 _ = try fg.wip.brCond(is_err, return_block, continue_block);5987 _ = try fg.wip.brCond(is_err, return_block, continue_block);
59885988
5989 fg.wip.cursor = .{ .block = return_block };5989 fg.wip.cursor = .{ .block = return_block };
5990 try fg.genBody(body);5990 try fg.genBodyDebugScope(body);
59915991
5992 fg.wip.cursor = .{ .block = continue_block };5992 fg.wip.cursor = .{ .block = continue_block };
5993 }5993 }
...@@ -6060,13 +6060,13 @@ pub const FuncGen = struct {...@@ -6060,13 +6060,13 @@ pub const FuncGen = struct {
6060 }6060 }
60616061
6062 self.wip.cursor = .{ .block = case_block };6062 self.wip.cursor = .{ .block = case_block };
6063 try self.genBody(case_body);6063 try self.genBodyDebugScope(case_body);
6064 }6064 }
60656065
6066 self.wip.cursor = .{ .block = else_block };6066 self.wip.cursor = .{ .block = else_block };
6067 const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra_index..][0..switch_br.data.else_body_len]);6067 const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra_index..][0..switch_br.data.else_body_len]);
6068 if (else_body.len != 0) {6068 if (else_body.len != 0) {
6069 try self.genBody(else_body);6069 try self.genBodyDebugScope(else_body);
6070 } else {6070 } else {
6071 _ = try self.wip.@"unreachable"();6071 _ = try self.wip.@"unreachable"();
6072 }6072 }
...@@ -6085,7 +6085,7 @@ pub const FuncGen = struct {...@@ -6085,7 +6085,7 @@ pub const FuncGen = struct {
6085 _ = try self.wip.br(loop_block);6085 _ = try self.wip.br(loop_block);
60866086
6087 self.wip.cursor = .{ .block = loop_block };6087 self.wip.cursor = .{ .block = loop_block };
6088 try self.genBody(body);6088 try self.genBodyDebugScope(body);
60896089
6090 // TODO instead of this logic, change AIR to have the property that6090 // TODO instead of this logic, change AIR to have the property that
6091 // every block is guaranteed to end with a noreturn instruction.6091 // every block is guaranteed to end with a noreturn instruction.