| ... | ... | @@ -1593,53 +1593,16 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1593 | 1593 | } |
| 1594 | 1594 | } |
| 1595 | 1595 | |
| 1596 | | // We would like to rely on the mechanism below even for comptime values. |
| 1597 | | // However in the case that the pointer points to comptime-mutable value, |
| 1598 | | // we cannot do it. |
| 1599 | | if (try sema.resolveDefinedValue(block, src, ptr)) |ptr_val| { |
| 1600 | | if (ptr_val.isComptimeMutablePtr()) { |
| 1601 | | const sentinel_val = try sema.addConstant(pointee_ty, Value.initTag(.unreachable_value)); |
| 1602 | | const coerced = try sema.coerce(block, sema.typeOf(ptr).childType(), sentinel_val, src); |
| 1603 | | |
| 1604 | | var res_ptr = ptr_val; |
| 1605 | | var cur_val = (try sema.resolveMaybeUndefVal(block, .unneeded, coerced)).?; |
| 1606 | | while (true) switch (cur_val.tag()) { |
| 1607 | | .unreachable_value => break, |
| 1608 | | .opt_payload => { |
| 1609 | | res_ptr = try Value.Tag.opt_payload_ptr.create(sema.arena, res_ptr); |
| 1610 | | cur_val = cur_val.castTag(.opt_payload).?.data; |
| 1611 | | }, |
| 1612 | | .eu_payload => { |
| 1613 | | res_ptr = try Value.Tag.eu_payload_ptr.create(sema.arena, res_ptr); |
| 1614 | | cur_val = cur_val.castTag(.eu_payload).?.data; |
| 1615 | | }, |
| 1616 | | else => { |
| 1617 | | if (std.debug.runtime_safety) { |
| 1618 | | std.debug.panic("unexpected Value tag for coerce_result_ptr: {s}", .{ |
| 1619 | | cur_val.tag(), |
| 1620 | | }); |
| 1621 | | } else { |
| 1622 | | unreachable; |
| 1623 | | } |
| 1624 | | }, |
| 1625 | | }; |
| 1626 | | |
| 1627 | | const ptr_ty = try Type.ptr(sema.arena, .{ |
| 1628 | | .pointee_type = pointee_ty, |
| 1629 | | .@"addrspace" = addr_space, |
| 1630 | | }); |
| 1631 | | return sema.addConstant(ptr_ty, res_ptr); |
| 1632 | | } |
| 1633 | | } |
| 1634 | | |
| 1635 | 1596 | // Make a dummy store through the pointer to test the coercion. |
| 1636 | 1597 | // We will then use the generated instructions to decide what |
| 1637 | 1598 | // kind of transformations to make on the result pointer. |
| 1638 | 1599 | var trash_block = block.makeSubBlock(); |
| 1600 | trash_block.is_comptime = false; |
| 1639 | 1601 | defer trash_block.instructions.deinit(sema.gpa); |
| 1640 | 1602 | |
| 1603 | const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr)); |
| 1641 | 1604 | const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value); |
| 1642 | | try sema.storePtr(&trash_block, src, ptr, dummy_operand); |
| 1605 | try sema.storePtr(&trash_block, src, dummy_ptr, dummy_operand); |
| 1643 | 1606 | |
| 1644 | 1607 | { |
| 1645 | 1608 | const air_tags = sema.air_instructions.items(.tag); |
| ... | ... | @@ -1670,6 +1633,9 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1670 | 1633 | switch (air_tags[trash_inst]) { |
| 1671 | 1634 | .bitcast => { |
| 1672 | 1635 | if (Air.indexToRef(trash_inst) == dummy_operand) { |
| 1636 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { |
| 1637 | return sema.addConstant(ptr_ty, ptr_val); |
| 1638 | } |
| 1673 | 1639 | return sema.bitCast(block, ptr_ty, new_ptr, src); |
| 1674 | 1640 | } |
| 1675 | 1641 | const ty_op = air_datas[trash_inst].ty_op; |
| ... | ... | @@ -1678,7 +1644,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1678 | 1644 | .pointee_type = operand_ty, |
| 1679 | 1645 | .@"addrspace" = addr_space, |
| 1680 | 1646 | }); |
| 1681 | | new_ptr = try sema.bitCast(block, ptr_operand_ty, new_ptr, src); |
| 1647 | if (try sema.resolveDefinedValue(block, src, new_ptr)) |ptr_val| { |
| 1648 | new_ptr = try sema.addConstant(ptr_operand_ty, ptr_val); |
| 1649 | } else { |
| 1650 | new_ptr = try sema.bitCast(block, ptr_operand_ty, new_ptr, src); |
| 1651 | } |
| 1682 | 1652 | }, |
| 1683 | 1653 | .wrap_optional => { |
| 1684 | 1654 | new_ptr = try sema.analyzeOptionalPayloadPtr(block, src, new_ptr, false, true); |