| ... | @@ -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(); |
| 1234 | | 1234 | |
| 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 | else | 2060 | 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 | } |
| 2293 | | 2293 | |
| | 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`. |
| | 2298 | fn 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 | |
| 2294 | fn blockExpr( | 2341 | fn blockExpr( |
| 2295 | gz: *GenZir, | 2342 | gz: *GenZir, |
| 2296 | scope: *Scope, | 2343 | scope: *Scope, |
| ... | @@ -4102,7 +4149,7 @@ fn fnDecl( | ... | @@ -4102,7 +4149,7 @@ fn fnDecl( |
| 4102 | assert(param_type_node != 0); | 4149 | assert(param_type_node != 0); |
| 4103 | var param_gz = decl_gz.makeSubBlock(scope); | 4150 | var param_gz = decl_gz.makeSubBlock(scope); |
| 4104 | defer param_gz.unstack(); | 4151 | defer param_gz.unstack(); |
| 4105 | const param_type = try expr(&param_gz, params_scope, coerced_type_ri, param_type_node); | 4152 | 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); | 4153 | 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); | 4154 | _ = try param_gz.addBreakWithSrcNode(.break_inline, param_inst_expected, param_type, param_type_node); |
| 4108 | | 4155 | |
| ... | @@ -4220,7 +4267,7 @@ fn fnDecl( | ... | @@ -4220,7 +4267,7 @@ fn fnDecl( |
| 4220 | var ret_gz = decl_gz.makeSubBlock(params_scope); | 4267 | var ret_gz = decl_gz.makeSubBlock(params_scope); |
| 4221 | defer ret_gz.unstack(); | 4268 | defer ret_gz.unstack(); |
| 4222 | const ret_ref: Zir.Inst.Ref = inst: { | 4269 | const ret_ref: Zir.Inst.Ref = inst: { |
| 4223 | const inst = try expr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type); | 4270 | const inst = try fullBodyExpr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type); |
| 4224 | if (ret_gz.instructionsSlice().len == 0) { | 4271 | if (ret_gz.instructionsSlice().len == 0) { |
| 4225 | // In this case we will send a len=0 body which can be encoded more efficiently. | 4272 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 4226 | break :inst inst; | 4273 | break :inst inst; |
| ... | @@ -4285,7 +4332,7 @@ fn fnDecl( | ... | @@ -4285,7 +4332,7 @@ fn fnDecl( |
| 4285 | const lbrace_line = astgen.source_line - decl_gz.decl_line; | 4332 | const lbrace_line = astgen.source_line - decl_gz.decl_line; |
| 4286 | const lbrace_column = astgen.source_column; | 4333 | const lbrace_column = astgen.source_column; |
| 4287 | | 4334 | |
| 4288 | _ = try expr(&fn_gz, params_scope, .{ .rl = .none }, body_node); | 4335 | _ = try fullBodyExpr(&fn_gz, params_scope, .{ .rl = .none }, body_node); |
| 4289 | try checkUsed(gz, &fn_gz.base, params_scope); | 4336 | try checkUsed(gz, &fn_gz.base, params_scope); |
| 4290 | | 4337 | |
| 4291 | if (!fn_gz.endsWithNoReturn()) { | 4338 | if (!fn_gz.endsWithNoReturn()) { |
| ... | @@ -4471,19 +4518,19 @@ fn globalVarDecl( | ... | @@ -4471,19 +4518,19 @@ fn globalVarDecl( |
| 4471 | | 4518 | |
| 4472 | var align_gz = block_scope.makeSubBlock(scope); | 4519 | var align_gz = block_scope.makeSubBlock(scope); |
| 4473 | if (var_decl.ast.align_node != 0) { | 4520 | 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); | 4521 | 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); | 4522 | _ = try align_gz.addBreakWithSrcNode(.break_inline, decl_inst, align_inst, node); |
| 4476 | } | 4523 | } |
| 4477 | | 4524 | |
| 4478 | var linksection_gz = align_gz.makeSubBlock(scope); | 4525 | var linksection_gz = align_gz.makeSubBlock(scope); |
| 4479 | if (var_decl.ast.section_node != 0) { | 4526 | 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); | 4527 | 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); | 4528 | _ = try linksection_gz.addBreakWithSrcNode(.break_inline, decl_inst, linksection_inst, node); |
| 4482 | } | 4529 | } |
| 4483 | | 4530 | |
| 4484 | var addrspace_gz = linksection_gz.makeSubBlock(scope); | 4531 | var addrspace_gz = linksection_gz.makeSubBlock(scope); |
| 4485 | if (var_decl.ast.addrspace_node != 0) { | 4532 | 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); | 4533 | 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); | 4534 | _ = try addrspace_gz.addBreakWithSrcNode(.break_inline, decl_inst, addrspace_inst, node); |
| 4488 | } | 4535 | } |
| 4489 | | 4536 | |
| ... | @@ -4532,7 +4579,7 @@ fn comptimeDecl( | ... | @@ -4532,7 +4579,7 @@ fn comptimeDecl( |
| 4532 | }; | 4579 | }; |
| 4533 | defer decl_block.unstack(); | 4580 | defer decl_block.unstack(); |
| 4534 | | 4581 | |
| 4535 | const block_result = try expr(&decl_block, &decl_block.base, .{ .rl = .none }, body_node); | 4582 | 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)) { | 4583 | if (decl_block.isEmpty() or !decl_block.refIsNoReturn(block_result)) { |
| 4537 | _ = try decl_block.addBreak(.break_inline, decl_inst, .void_value); | 4584 | _ = try decl_block.addBreak(.break_inline, decl_inst, .void_value); |
| 4538 | } | 4585 | } |
| ... | @@ -4734,7 +4781,7 @@ fn testDecl( | ... | @@ -4734,7 +4781,7 @@ fn testDecl( |
| 4734 | const lbrace_line = astgen.source_line - decl_block.decl_line; | 4781 | const lbrace_line = astgen.source_line - decl_block.decl_line; |
| 4735 | const lbrace_column = astgen.source_column; | 4782 | const lbrace_column = astgen.source_column; |
| 4736 | | 4783 | |
| 4737 | const block_result = try expr(&fn_block, &fn_block.base, .{ .rl = .none }, body_node); | 4784 | 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)) { | 4785 | if (fn_block.isEmpty() or !fn_block.refIsNoReturn(block_result)) { |
| 4739 | | 4786 | |
| 4740 | // As our last action before the return, "pop" the error trace if needed | 4787 | // As our last action before the return, "pop" the error trace if needed |
| ... | @@ -5981,7 +6028,7 @@ fn orelseCatchExpr( | ... | @@ -5981,7 +6028,7 @@ fn orelseCatchExpr( |
| 5981 | break :blk &err_val_scope.base; | 6028 | break :blk &err_val_scope.base; |
| 5982 | }; | 6029 | }; |
| 5983 | | 6030 | |
| 5984 | const else_result = try expr(&else_scope, else_sub_scope, block_scope.break_result_info, rhs); | 6031 | const else_result = try fullBodyExpr(&else_scope, else_sub_scope, block_scope.break_result_info, rhs); |
| 5985 | if (!else_scope.endsWithNoReturn()) { | 6032 | if (!else_scope.endsWithNoReturn()) { |
| 5986 | // As our last action before the break, "pop" the error trace if needed | 6033 | // As our last action before the break, "pop" the error trace if needed |
| 5987 | if (do_err_trace) | 6034 | if (do_err_trace) |
| ... | @@ -6149,7 +6196,7 @@ fn boolBinOp( | ... | @@ -6149,7 +6196,7 @@ fn boolBinOp( |
| 6149 | | 6196 | |
| 6150 | var rhs_scope = gz.makeSubBlock(scope); | 6197 | var rhs_scope = gz.makeSubBlock(scope); |
| 6151 | defer rhs_scope.unstack(); | 6198 | defer rhs_scope.unstack(); |
| 6152 | const rhs = try expr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, node_datas[node].rhs); | 6199 | const rhs = try fullBodyExpr(&rhs_scope, &rhs_scope.base, coerced_bool_ri, node_datas[node].rhs); |
| 6153 | if (!gz.refIsNoReturn(rhs)) { | 6200 | if (!gz.refIsNoReturn(rhs)) { |
| 6154 | _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs); | 6201 | _ = try rhs_scope.addBreakWithSrcNode(.break_inline, bool_br, rhs, node_datas[node].rhs); |
| 6155 | } | 6202 | } |
| ... | @@ -6293,7 +6340,7 @@ fn ifExpr( | ... | @@ -6293,7 +6340,7 @@ fn ifExpr( |
| 6293 | } | 6340 | } |
| 6294 | }; | 6341 | }; |
| 6295 | | 6342 | |
| 6296 | const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, then_node); | 6343 | 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); | 6344 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 6298 | if (!then_scope.endsWithNoReturn()) { | 6345 | if (!then_scope.endsWithNoReturn()) { |
| 6299 | _ = try then_scope.addBreakWithSrcNode(.@"break", block, then_result, then_node); | 6346 | _ = try then_scope.addBreakWithSrcNode(.@"break", block, then_result, then_node); |
| ... | @@ -6335,7 +6382,7 @@ fn ifExpr( | ... | @@ -6335,7 +6382,7 @@ fn ifExpr( |
| 6335 | break :s &else_scope.base; | 6382 | break :s &else_scope.base; |
| 6336 | } | 6383 | } |
| 6337 | }; | 6384 | }; |
| 6338 | const else_result = try expr(&else_scope, sub_scope, block_scope.break_result_info, else_node); | 6385 | const else_result = try fullBodyExpr(&else_scope, sub_scope, block_scope.break_result_info, else_node); |
| 6339 | if (!else_scope.endsWithNoReturn()) { | 6386 | if (!else_scope.endsWithNoReturn()) { |
| 6340 | // As our last action before the break, "pop" the error trace if needed | 6387 | // As our last action before the break, "pop" the error trace if needed |
| 6341 | if (do_err_trace) | 6388 | if (do_err_trace) |
| ... | @@ -6444,7 +6491,7 @@ fn whileExpr( | ... | @@ -6444,7 +6491,7 @@ fn whileExpr( |
| 6444 | } = c: { | 6491 | } = c: { |
| 6445 | if (while_full.error_token) |_| { | 6492 | if (while_full.error_token) |_| { |
| 6446 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; | 6493 | 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); | 6494 | 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; | 6495 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err; |
| 6449 | break :c .{ | 6496 | break :c .{ |
| 6450 | .inst = err_union, | 6497 | .inst = err_union, |
| ... | @@ -6452,14 +6499,14 @@ fn whileExpr( | ... | @@ -6452,14 +6499,14 @@ fn whileExpr( |
| 6452 | }; | 6499 | }; |
| 6453 | } else if (while_full.payload_token) |_| { | 6500 | } else if (while_full.payload_token) |_| { |
| 6454 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; | 6501 | 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); | 6502 | 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; | 6503 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null; |
| 6457 | break :c .{ | 6504 | break :c .{ |
| 6458 | .inst = optional, | 6505 | .inst = optional, |
| 6459 | .bool_bit = try cond_scope.addUnNode(tag, optional, while_full.ast.cond_expr), | 6506 | .bool_bit = try cond_scope.addUnNode(tag, optional, while_full.ast.cond_expr), |
| 6460 | }; | 6507 | }; |
| 6461 | } else { | 6508 | } else { |
| 6462 | const cond = try expr(&cond_scope, &cond_scope.base, coerced_bool_ri, while_full.ast.cond_expr); | 6509 | const cond = try fullBodyExpr(&cond_scope, &cond_scope.base, coerced_bool_ri, while_full.ast.cond_expr); |
| 6463 | break :c .{ | 6510 | break :c .{ |
| 6464 | .inst = cond, | 6511 | .inst = cond, |
| 6465 | .bool_bit = cond, | 6512 | .bool_bit = cond, |
| ... | @@ -6582,7 +6629,11 @@ fn whileExpr( | ... | @@ -6582,7 +6629,11 @@ fn whileExpr( |
| 6582 | } | 6629 | } |
| 6583 | | 6630 | |
| 6584 | continue_scope.instructions_top = continue_scope.instructions.items.len; | 6631 | continue_scope.instructions_top = continue_scope.instructions.items.len; |
| 6585 | _ = try unusedResultExpr(&continue_scope, &continue_scope.base, then_node); | 6632 | { |
| | 6633 | try emitDbgNode(&continue_scope, then_node); |
| | 6634 | const unused_result = try fullBodyExpr(&continue_scope, &continue_scope.base, .{ .rl = .none }, then_node); |
| | 6635 | _ = try addEnsureResult(&continue_scope, unused_result, then_node); |
| | 6636 | } |
| 6586 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 6637 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| 6587 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; | 6638 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 6588 | if (!continue_scope.endsWithNoReturn()) { | 6639 | if (!continue_scope.endsWithNoReturn()) { |
| ... | @@ -6626,7 +6677,7 @@ fn whileExpr( | ... | @@ -6626,7 +6677,7 @@ fn whileExpr( |
| 6626 | // control flow apply to outer loops; not this one. | 6677 | // control flow apply to outer loops; not this one. |
| 6627 | loop_scope.continue_block = .none; | 6678 | loop_scope.continue_block = .none; |
| 6628 | loop_scope.break_block = .none; | 6679 | loop_scope.break_block = .none; |
| 6629 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_info, else_node); | 6680 | const else_result = try fullBodyExpr(&else_scope, sub_scope, loop_scope.break_result_info, else_node); |
| 6630 | if (is_statement) { | 6681 | if (is_statement) { |
| 6631 | _ = try addEnsureResult(&else_scope, else_result, else_node); | 6682 | _ = try addEnsureResult(&else_scope, else_result, else_node); |
| 6632 | } | 6683 | } |
| ... | @@ -6894,7 +6945,7 @@ fn forExpr( | ... | @@ -6894,7 +6945,7 @@ fn forExpr( |
| 6894 | break :blk capture_sub_scope; | 6945 | break :blk capture_sub_scope; |
| 6895 | }; | 6946 | }; |
| 6896 | | 6947 | |
| 6897 | const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, then_node); | 6948 | const then_result = try fullBodyExpr(&then_scope, then_sub_scope, .{ .rl = .none }, then_node); |
| 6898 | _ = try addEnsureResult(&then_scope, then_result, then_node); | 6949 | _ = try addEnsureResult(&then_scope, then_result, then_node); |
| 6899 | | 6950 | |
| 6900 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 6951 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| ... | @@ -6913,7 +6964,7 @@ fn forExpr( | ... | @@ -6913,7 +6964,7 @@ fn forExpr( |
| 6913 | // control flow apply to outer loops; not this one. | 6964 | // control flow apply to outer loops; not this one. |
| 6914 | loop_scope.continue_block = .none; | 6965 | loop_scope.continue_block = .none; |
| 6915 | loop_scope.break_block = .none; | 6966 | loop_scope.break_block = .none; |
| 6916 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_info, else_node); | 6967 | const else_result = try fullBodyExpr(&else_scope, sub_scope, loop_scope.break_result_info, else_node); |
| 6917 | if (is_statement) { | 6968 | if (is_statement) { |
| 6918 | _ = try addEnsureResult(&else_scope, else_result, else_node); | 6969 | _ = try addEnsureResult(&else_scope, else_result, else_node); |
| 6919 | } | 6970 | } |
| ... | @@ -7388,7 +7439,7 @@ fn switchExprErrUnion( | ... | @@ -7388,7 +7439,7 @@ fn switchExprErrUnion( |
| 7388 | } | 7439 | } |
| 7389 | | 7440 | |
| 7390 | const target_expr_node = case.ast.target_expr; | 7441 | 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); | 7442 | 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 capture | 7443 | // check capture_scope, not err_scope to avoid false positive unused error capture |
| 7393 | try checkUsed(parent_gz, &case_scope.base, err_scope.parent); | 7444 | try checkUsed(parent_gz, &case_scope.base, err_scope.parent); |
| 7394 | const uses_err = err_scope.used != 0 or err_scope.discarded != 0; | 7445 | const uses_err = err_scope.used != 0 or err_scope.discarded != 0; |
| ... | @@ -7849,7 +7900,7 @@ fn switchExpr( | ... | @@ -7849,7 +7900,7 @@ fn switchExpr( |
| 7849 | try case_scope.addDbgVar(.dbg_var_val, dbg_var_tag_name, dbg_var_tag_inst); | 7900 | try case_scope.addDbgVar(.dbg_var_val, dbg_var_tag_name, dbg_var_tag_inst); |
| 7850 | } | 7901 | } |
| 7851 | const target_expr_node = case.ast.target_expr; | 7902 | 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); | 7903 | 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); | 7904 | try checkUsed(parent_gz, &case_scope.base, sub_scope); |
| 7854 | if (!parent_gz.refIsNoReturn(case_result)) { | 7905 | if (!parent_gz.refIsNoReturn(case_result)) { |
| 7855 | _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node); | 7906 | _ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node); |
| ... | @@ -9752,7 +9803,7 @@ fn cImport( | ... | @@ -9752,7 +9803,7 @@ fn cImport( |
| 9752 | defer block_scope.unstack(); | 9803 | defer block_scope.unstack(); |
| 9753 | | 9804 | |
| 9754 | const block_inst = try gz.makeBlockInst(.c_import, node); | 9805 | const block_inst = try gz.makeBlockInst(.c_import, node); |
| 9755 | const block_result = try expr(&block_scope, &block_scope.base, .{ .rl = .none }, body_node); | 9806 | const block_result = try fullBodyExpr(&block_scope, &block_scope.base, .{ .rl = .none }, body_node); |
| 9756 | _ = try gz.addUnNode(.ensure_result_used, block_result, node); | 9807 | _ = try gz.addUnNode(.ensure_result_used, block_result, node); |
| 9757 | if (!gz.refIsNoReturn(block_result)) { | 9808 | if (!gz.refIsNoReturn(block_result)) { |
| 9758 | _ = try block_scope.addBreak(.break_inline, block_inst, .void_value); | 9809 | _ = try block_scope.addBreak(.break_inline, block_inst, .void_value); |
| ... | @@ -9835,7 +9886,7 @@ fn callExpr( | ... | @@ -9835,7 +9886,7 @@ fn callExpr( |
| 9835 | defer arg_block.unstack(); | 9886 | defer arg_block.unstack(); |
| 9836 | | 9887 | |
| 9837 | // `call_inst` is reused to provide the param type. | 9888 | // `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); | 9889 | 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); | 9890 | _ = try arg_block.addBreakWithSrcNode(.break_inline, call_index, arg_ref, param_node); |
| 9840 | | 9891 | |
| 9841 | const body = arg_block.instructionsSlice(); | 9892 | const body = arg_block.instructionsSlice(); |
| ... | @@ -10871,11 +10922,11 @@ fn rvalueInner( | ... | @@ -10871,11 +10922,11 @@ fn rvalueInner( |
| 10871 | .ty => |ty_inst| { | 10922 | .ty => |ty_inst| { |
| 10872 | // Quickly eliminate some common, unnecessary type coercion. | 10923 | // Quickly eliminate some common, unnecessary type coercion. |
| 10873 | const as_ty = @as(u64, @intFromEnum(Zir.Inst.Ref.type_type)) << 32; | 10924 | 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; | 10925 | const as_bool = @as(u64, @intFromEnum(Zir.Inst.Ref.bool_type)) << 32; |
| | 10926 | const as_void = @as(u64, @intFromEnum(Zir.Inst.Ref.void_type)) << 32; |
| | 10927 | const as_comptime_int = @as(u64, @intFromEnum(Zir.Inst.Ref.comptime_int_type)) << 32; |
| 10876 | const as_usize = @as(u64, @intFromEnum(Zir.Inst.Ref.usize_type)) << 32; | 10928 | const as_usize = @as(u64, @intFromEnum(Zir.Inst.Ref.usize_type)) << 32; |
| 10877 | const as_u8 = @as(u64, @intFromEnum(Zir.Inst.Ref.u8_type)) << 32; | 10929 | const as_u8 = @as(u64, @intFromEnum(Zir.Inst.Ref.u8_type)) << 32; |
| 10878 | const as_void = @as(u64, @intFromEnum(Zir.Inst.Ref.void_type)) << 32; | | |
| 10879 | switch ((@as(u64, @intFromEnum(ty_inst)) << 32) | @as(u64, @intFromEnum(result))) { | 10930 | switch ((@as(u64, @intFromEnum(ty_inst)) << 32) | @as(u64, @intFromEnum(result))) { |
| 10880 | as_ty | @intFromEnum(Zir.Inst.Ref.u1_type), | 10931 | as_ty | @intFromEnum(Zir.Inst.Ref.u1_type), |
| 10881 | as_ty | @intFromEnum(Zir.Inst.Ref.u8_type), | 10932 | as_ty | @intFromEnum(Zir.Inst.Ref.u8_type), |
| ... | @@ -11694,7 +11745,8 @@ const GenZir = struct { | ... | @@ -11694,7 +11745,8 @@ const GenZir = struct { |
| 11694 | /// Whether we're in an expression within a `@TypeOf` operand. In this case, closure of runtime | 11745 | /// Whether we're in an expression within a `@TypeOf` operand. In this case, closure of runtime |
| 11695 | /// variables is permitted where it is usually not. | 11746 | /// variables is permitted where it is usually not. |
| 11696 | is_typeof: bool = false, | 11747 | is_typeof: bool = false, |
| 11697 | /// This is set to true for inline loops; false otherwise. | 11748 | /// This is set to true for a `GenZir` of a `block_inline`, indicating that |
| | 11749 | /// exits from this block should use `break_inline` rather than `break`. |
| 11698 | is_inline: bool = false, | 11750 | is_inline: bool = false, |
| 11699 | c_import: bool = false, | 11751 | c_import: bool = false, |
| 11700 | /// How decls created in this scope should be named. | 11752 | /// How decls created in this scope should be named. |