authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-26 10:47:38+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-26 12:52:07-07:00
logbf5c055562b88f1a686815c85d2a29c0889a97ee
tree419fe3dc7cab67d43f0cc5b85040340476ab42a1
parentbff7714a7c681ec41abf45a6cfc74a32ff8655dd

stage2: unify runtime and comptime coerce_result_ptr


1 files changed, 11 insertions(+), 41 deletions(-)

src/Sema.zig+11-41
......@@ -1593,53 +1593,16 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
15931593 }
15941594 }
15951595
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
16351596 // Make a dummy store through the pointer to test the coercion.
16361597 // We will then use the generated instructions to decide what
16371598 // kind of transformations to make on the result pointer.
16381599 var trash_block = block.makeSubBlock();
1600 trash_block.is_comptime = false;
16391601 defer trash_block.instructions.deinit(sema.gpa);
16401602
1603 const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr));
16411604 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);
16431606
16441607 {
16451608 const air_tags = sema.air_instructions.items(.tag);
......@@ -1670,6 +1633,9 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
16701633 switch (air_tags[trash_inst]) {
16711634 .bitcast => {
16721635 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 }
16731639 return sema.bitCast(block, ptr_ty, new_ptr, src);
16741640 }
16751641 const ty_op = air_datas[trash_inst].ty_op;
......@@ -1678,7 +1644,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
16781644 .pointee_type = operand_ty,
16791645 .@"addrspace" = addr_space,
16801646 });
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 }
16821652 },
16831653 .wrap_optional => {
16841654 new_ptr = try sema.analyzeOptionalPayloadPtr(block, src, new_ptr, false, true);