| ... | ... | @@ -1807,6 +1807,8 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1807 | 1807 | .@"break"; |
| 1808 | 1808 | |
| 1809 | 1809 | if (rhs == 0) { |
| 1810 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| 1811 | |
| 1810 | 1812 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); |
| 1811 | 1813 | return Zir.Inst.Ref.unreachable_value; |
| 1812 | 1814 | } |
| ... | ... | @@ -1819,12 +1821,15 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1819 | 1821 | const prev_rvalue_noresult = parent_gz.rvalue_noresult; |
| 1820 | 1822 | parent_gz.rvalue_noresult = .none; |
| 1821 | 1823 | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_loc, rhs, node); |
| 1824 | const search_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| 1822 | 1825 | parent_gz.rvalue_noresult = prev_rvalue_noresult; |
| 1823 | 1826 | |
| 1827 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| 1828 | |
| 1824 | 1829 | switch (block_gz.break_result_loc) { |
| 1825 | 1830 | .block_ptr => { |
| 1826 | 1831 | const br = try parent_gz.addBreak(break_tag, block_inst, operand); |
| 1827 | | try block_gz.labeled_breaks.append(astgen.gpa, br); |
| 1832 | try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index }); |
| 1828 | 1833 | }, |
| 1829 | 1834 | .ptr => { |
| 1830 | 1835 | // In this case we don't have any mechanism to intercept it; |
| ... | ... | @@ -1843,13 +1848,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1843 | 1848 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 1844 | 1849 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1845 | 1850 | .namespace => break, |
| 1846 | | .defer_normal => { |
| 1847 | | const defer_scope = scope.cast(Scope.Defer).?; |
| 1848 | | scope = defer_scope.parent; |
| 1849 | | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| 1850 | | try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node); |
| 1851 | | }, |
| 1852 | | .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1851 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1853 | 1852 | .top => unreachable, |
| 1854 | 1853 | } |
| 1855 | 1854 | } |
| ... | ... | @@ -2030,7 +2029,7 @@ fn labeledBlockExpr( |
| 2030 | 2029 | // The code took advantage of the result location as a pointer. |
| 2031 | 2030 | // Turn the break instruction operands into void. |
| 2032 | 2031 | for (block_scope.labeled_breaks.items) |br| { |
| 2033 | | zir_datas[br].@"break".operand = .void_value; |
| 2032 | zir_datas[br.br].@"break".operand = .void_value; |
| 2034 | 2033 | } |
| 2035 | 2034 | try block_scope.setBlockBody(block_inst); |
| 2036 | 2035 | |
| ... | ... | @@ -2047,17 +2046,17 @@ fn labeledBlockExpr( |
| 2047 | 2046 | for (block_scope.labeled_breaks.items) |br| { |
| 2048 | 2047 | // We expect the `store_to_block_ptr` to be created between 1-3 instructions |
| 2049 | 2048 | // prior to the break. |
| 2050 | | var search_index = br -| 3; |
| 2051 | | while (search_index < br) : (search_index += 1) { |
| 2049 | var search_index = br.search -| 3; |
| 2050 | while (search_index < br.search) : (search_index += 1) { |
| 2052 | 2051 | if (zir_tags[search_index] == .store_to_block_ptr and |
| 2053 | 2052 | zir_datas[search_index].bin.lhs == block_scope.rl_ptr) |
| 2054 | 2053 | { |
| 2055 | 2054 | zir_tags[search_index] = .as; |
| 2056 | 2055 | zir_datas[search_index].bin = .{ |
| 2057 | 2056 | .lhs = block_scope.rl_ty_inst, |
| 2058 | | .rhs = zir_datas[br].@"break".operand, |
| 2057 | .rhs = zir_datas[br.br].@"break".operand, |
| 2059 | 2058 | }; |
| 2060 | | zir_datas[br].@"break".operand = indexToRef(search_index); |
| 2059 | zir_datas[br.br].@"break".operand = indexToRef(search_index); |
| 2061 | 2060 | break; |
| 2062 | 2061 | } |
| 2063 | 2062 | } else unreachable; |
| ... | ... | @@ -9719,7 +9718,7 @@ const GenZir = struct { |
| 9719 | 9718 | break_count: usize = 0, |
| 9720 | 9719 | /// Tracks `break :foo bar` instructions so they can possibly be elided later if |
| 9721 | 9720 | /// the labeled block ends up not needing a result location pointer. |
| 9722 | | labeled_breaks: ArrayListUnmanaged(Zir.Inst.Index) = .{}, |
| 9721 | labeled_breaks: ArrayListUnmanaged(struct { br: Zir.Inst.Index, search: Zir.Inst.Index }) = .{}, |
| 9723 | 9722 | |
| 9724 | 9723 | suspend_node: Ast.Node.Index = 0, |
| 9725 | 9724 | nosuspend_node: Ast.Node.Index = 0, |