| ... | @@ -553,6 +553,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In | ... | @@ -553,6 +553,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 553 | mod, | 553 | mod, |
| 554 | scope, | 554 | scope, |
| 555 | rl, | 555 | rl, |
| | 556 | node, |
| 556 | node_datas[node].lhs, | 557 | node_datas[node].lhs, |
| 557 | main_tokens[node], | 558 | main_tokens[node], |
| 558 | .is_null_ptr, | 559 | .is_null_ptr, |
| ... | @@ -565,6 +566,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In | ... | @@ -565,6 +566,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 565 | mod, | 566 | mod, |
| 566 | scope, | 567 | scope, |
| 567 | rl, | 568 | rl, |
| | 569 | node, |
| 568 | node_datas[node].lhs, | 570 | node_datas[node].lhs, |
| 569 | main_tokens[node], | 571 | main_tokens[node], |
| 570 | .is_null, | 572 | .is_null, |
| ... | @@ -1633,6 +1635,7 @@ fn orelseCatchExpr( | ... | @@ -1633,6 +1635,7 @@ fn orelseCatchExpr( |
| 1633 | mod: *Module, | 1635 | mod: *Module, |
| 1634 | scope: *Scope, | 1636 | scope: *Scope, |
| 1635 | rl: ResultLoc, | 1637 | rl: ResultLoc, |
| | 1638 | node: ast.Node.Index, |
| 1636 | lhs: ast.Node.Index, | 1639 | lhs: ast.Node.Index, |
| 1637 | op_token: ast.TokenIndex, | 1640 | op_token: ast.TokenIndex, |
| 1638 | cond_op: zir.Inst.Tag, | 1641 | cond_op: zir.Inst.Tag, |
| ... | @@ -1641,16 +1644,11 @@ fn orelseCatchExpr( | ... | @@ -1641,16 +1644,11 @@ fn orelseCatchExpr( |
| 1641 | rhs: ast.Node.Index, | 1644 | rhs: ast.Node.Index, |
| 1642 | payload_token: ?ast.TokenIndex, | 1645 | payload_token: ?ast.TokenIndex, |
| 1643 | ) InnerError!zir.Inst.Ref { | 1646 | ) InnerError!zir.Inst.Ref { |
| 1644 | if (true) @panic("TODO update for zir-memory-layout"); | 1647 | const parent_gz = scope.getGenZir(); |
| 1645 | | | |
| 1646 | const gz = scope.getGenZir(); | | |
| 1647 | const tree = gz.tree(); | | |
| 1648 | | | |
| 1649 | var block_scope: Scope.GenZir = .{ | 1648 | var block_scope: Scope.GenZir = .{ |
| 1650 | .parent = scope, | 1649 | .parent = scope, |
| 1651 | .decl = scope.ownerDecl().?, | 1650 | .zir_code = parent_gz.zir_code, |
| 1652 | .arena = scope.arena(), | 1651 | .force_comptime = parent_gz.force_comptime, |
| 1653 | .force_comptime = gz.force_comptime, | | |
| 1654 | .instructions = .{}, | 1652 | .instructions = .{}, |
| 1655 | }; | 1653 | }; |
| 1656 | setBlockResultLoc(&block_scope, rl); | 1654 | setBlockResultLoc(&block_scope, rl); |
| ... | @@ -1661,62 +1659,73 @@ fn orelseCatchExpr( | ... | @@ -1661,62 +1659,73 @@ fn orelseCatchExpr( |
| 1661 | // type, whereas this expression has the optional type. Later we make | 1659 | // type, whereas this expression has the optional type. Later we make |
| 1662 | // up for this fact by calling rvalue on the else branch. | 1660 | // up for this fact by calling rvalue on the else branch. |
| 1663 | block_scope.break_count += 1; | 1661 | block_scope.break_count += 1; |
| 1664 | const operand_rl = try makeOptionalTypeResultLoc(mod, &block_scope.base, src, block_scope.break_result_loc); | 1662 | |
| | 1663 | // TODO handle catch |
| | 1664 | const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { |
| | 1665 | .ref => .ref, |
| | 1666 | .discard, .none, .block_ptr, .inferred_ptr, .bitcasted_ptr => .none, |
| | 1667 | .ty => |elem_ty| blk: { |
| | 1668 | const wrapped_ty = try block_scope.addUnNode(.optional_type, elem_ty, node); |
| | 1669 | break :blk .{ .ty = wrapped_ty }; |
| | 1670 | }, |
| | 1671 | .ptr => |ptr_ty| blk: { |
| | 1672 | const wrapped_ty = try block_scope.addUnNode(.optional_type_from_ptr_elem, ptr_ty, node); |
| | 1673 | break :blk .{ .ty = wrapped_ty }; |
| | 1674 | }, |
| | 1675 | }; |
| 1665 | const operand = try expr(mod, &block_scope.base, operand_rl, lhs); | 1676 | const operand = try expr(mod, &block_scope.base, operand_rl, lhs); |
| 1666 | const cond = try addZIRUnOp(mod, &block_scope.base, src, cond_op, operand); | 1677 | const cond = try block_scope.addUnTok(cond_op, operand, op_token); |
| 1667 | | 1678 | |
| 1668 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ | 1679 | const condbr = try block_scope.addCondBr(node); |
| 1669 | .condition = cond, | | |
| 1670 | .then_body = undefined, // populated below | | |
| 1671 | .else_body = undefined, // populated below | | |
| 1672 | }, .{}); | | |
| 1673 | | 1680 | |
| 1674 | const block = try addZIRInstBlock(mod, scope, src, .block, .{ | 1681 | const block = try parent_gz.addBlock(.block, node); |
| 1675 | .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items), | 1682 | try parent_gz.instructions.append(mod.gpa, block); |
| 1676 | }); | 1683 | try block_scope.setBlockBody(block); |
| 1677 | | 1684 | |
| 1678 | var then_scope: Scope.GenZir = .{ | 1685 | var then_scope: Scope.GenZir = .{ |
| 1679 | .parent = &block_scope.base, | 1686 | .parent = scope, |
| 1680 | .decl = block_scope.decl, | 1687 | .zir_code = parent_gz.zir_code, |
| 1681 | .arena = block_scope.arena, | | |
| 1682 | .force_comptime = block_scope.force_comptime, | 1688 | .force_comptime = block_scope.force_comptime, |
| 1683 | .instructions = .{}, | 1689 | .instructions = .{}, |
| 1684 | }; | 1690 | }; |
| 1685 | defer then_scope.instructions.deinit(mod.gpa); | 1691 | defer then_scope.instructions.deinit(mod.gpa); |
| 1686 | | 1692 | |
| 1687 | var err_val_scope: Scope.LocalVal = undefined; | 1693 | if (payload_token != null) @panic("TODO handle catch"); |
| 1688 | const then_sub_scope = blk: { | 1694 | // var err_val_scope: Scope.LocalVal = undefined; |
| 1689 | const payload = payload_token orelse break :blk &then_scope.base; | 1695 | // const then_sub_scope = blk: { |
| 1690 | if (mem.eql(u8, tree.tokenSlice(payload), "_")) { | 1696 | // const payload = payload_token orelse break :blk &then_scope.base; |
| 1691 | return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{}); | 1697 | // if (mem.eql(u8, tree.tokenSlice(payload), "_")) { |
| 1692 | } | 1698 | // return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{}); |
| 1693 | const err_name = try mod.identifierTokenString(scope, payload); | 1699 | // } |
| 1694 | err_val_scope = .{ | 1700 | // const err_name = try mod.identifierTokenString(scope, payload); |
| 1695 | .parent = &then_scope.base, | 1701 | // err_val_scope = .{ |
| 1696 | .gen_zir = &then_scope, | 1702 | // .parent = &then_scope.base, |
| 1697 | .name = err_name, | 1703 | // .gen_zir = &then_scope, |
| 1698 | .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand), | 1704 | // .name = err_name, |
| 1699 | }; | 1705 | // .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand), |
| 1700 | break :blk &err_val_scope.base; | 1706 | // }; |
| 1701 | }; | 1707 | // break :blk &err_val_scope.base; |
| | 1708 | // }; |
| 1702 | | 1709 | |
| 1703 | block_scope.break_count += 1; | 1710 | block_scope.break_count += 1; |
| 1704 | const then_result = try expr(mod, then_sub_scope, block_scope.break_result_loc, rhs); | 1711 | const then_result = try expr(mod, &then_scope.base, block_scope.break_result_loc, rhs); |
| | 1712 | // We hold off on the break instructions as well as copying the then/else |
| | 1713 | // instructions into place until we know whether to keep store_to_block_ptr |
| | 1714 | // instructions or not. |
| 1705 | | 1715 | |
| 1706 | var else_scope: Scope.GenZir = .{ | 1716 | var else_scope: Scope.GenZir = .{ |
| 1707 | .parent = &block_scope.base, | 1717 | .parent = scope, |
| 1708 | .decl = block_scope.decl, | 1718 | .zir_code = parent_gz.zir_code, |
| 1709 | .arena = block_scope.arena, | | |
| 1710 | .force_comptime = block_scope.force_comptime, | 1719 | .force_comptime = block_scope.force_comptime, |
| 1711 | .instructions = .{}, | 1720 | .instructions = .{}, |
| 1712 | }; | 1721 | }; |
| 1713 | defer else_scope.instructions.deinit(mod.gpa); | 1722 | defer else_scope.instructions.deinit(mod.gpa); |
| 1714 | | 1723 | |
| 1715 | // This could be a pointer or value depending on `unwrap_op`. | 1724 | // This could be a pointer or value depending on `unwrap_op`. |
| 1716 | const unwrapped_payload = try addZIRUnOp(mod, &else_scope.base, src, unwrap_op, operand); | 1725 | const unwrapped_payload = try else_scope.addUnNode(unwrap_op, operand, node); |
| 1717 | const else_result = switch (rl) { | 1726 | const else_result = switch (rl) { |
| 1718 | .ref => unwrapped_payload, | 1727 | .ref => unwrapped_payload, |
| 1719 | else => try rvalue(mod, &else_scope.base, block_scope.break_result_loc, unwrapped_payload), | 1728 | else => try rvalue(mod, &else_scope.base, block_scope.break_result_loc, unwrapped_payload, node), |
| 1720 | }; | 1729 | }; |
| 1721 | | 1730 | |
| 1722 | return finishThenElseBlock( | 1731 | return finishThenElseBlock( |
| ... | @@ -1729,8 +1738,8 @@ fn orelseCatchExpr( | ... | @@ -1729,8 +1738,8 @@ fn orelseCatchExpr( |
| 1729 | &else_scope, | 1738 | &else_scope, |
| 1730 | condbr, | 1739 | condbr, |
| 1731 | cond, | 1740 | cond, |
| 1732 | src, | 1741 | node, |
| 1733 | src, | 1742 | node, |
| 1734 | then_result, | 1743 | then_result, |
| 1735 | else_result, | 1744 | else_result, |
| 1736 | block, | 1745 | block, |