| ... | @@ -1593,53 +1593,16 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -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 | // Make a dummy store through the pointer to test the coercion. | 1596 | // Make a dummy store through the pointer to test the coercion. |
| 1636 | // We will then use the generated instructions to decide what | 1597 | // We will then use the generated instructions to decide what |
| 1637 | // kind of transformations to make on the result pointer. | 1598 | // kind of transformations to make on the result pointer. |
| 1638 | var trash_block = block.makeSubBlock(); | 1599 | var trash_block = block.makeSubBlock(); |
| | 1600 | trash_block.is_comptime = false; |
| 1639 | defer trash_block.instructions.deinit(sema.gpa); | 1601 | defer trash_block.instructions.deinit(sema.gpa); |
| 1640 | | 1602 | |
| | 1603 | const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr)); |
| 1641 | const dummy_operand = try trash_block.addBitCast(pointee_ty, .void_value); | 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 | const air_tags = sema.air_instructions.items(.tag); | 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,6 +1633,9 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1670 | switch (air_tags[trash_inst]) { | 1633 | switch (air_tags[trash_inst]) { |
| 1671 | .bitcast => { | 1634 | .bitcast => { |
| 1672 | if (Air.indexToRef(trash_inst) == dummy_operand) { | 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 | return sema.bitCast(block, ptr_ty, new_ptr, src); | 1639 | return sema.bitCast(block, ptr_ty, new_ptr, src); |
| 1674 | } | 1640 | } |
| 1675 | const ty_op = air_datas[trash_inst].ty_op; | 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,7 +1644,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 1678 | .pointee_type = operand_ty, | 1644 | .pointee_type = operand_ty, |
| 1679 | .@"addrspace" = addr_space, | 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 | .wrap_optional => { | 1653 | .wrap_optional => { |
| 1684 | new_ptr = try sema.analyzeOptionalPayloadPtr(block, src, new_ptr, false, true); | 1654 | new_ptr = try sema.analyzeOptionalPayloadPtr(block, src, new_ptr, false, true); |