aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2025-02-01 08:07:14 +0000
committerMatthew Lugg <mlugg@mlugg.co.uk>2025-02-01 15:48:45 +0000
commit3924f173af51c50ac18be2166fe115555241778e (patch)
treeee3fa65cc85dd6022af6533068dc3fb4f46461ab /src
parentc225b780e3944014300555c3b45eaccd7bc7c8ae (diff)
downloadzig-3924f173af51c50ac18be2166fe115555241778e.tar.gz
zig-3924f173af51c50ac18be2166fe115555241778e.zip
compiler: do not propagate result type to `try` operand
This commit effectively reverts 9e683f0, and hence un-accepts #19777. While nice in theory, this proposal turned out to have a few problems. Firstly, supplying a result type implicitly coerces the operand to this type -- that's the main point of result types! But for `try`, this is actually a bad idea; we want a redundant `try` to be a compile error, not to silently coerce the non-error value to an error union. In practice, this didn't always happen, because the implementation was buggy anyway; but when it did, it was really quite silly. For instance, `try try ... try .{ ... }` was an accepted expression, with the inner initializer being initially coerced to `E!E!...E!T`. Secondly, the result type inference here didn't play nicely with `return`. If you write `return try`, the operand would actually receive a result type of `E!E!T`, since the `return` gave a result type of `E!T` and the `try` wrapped it in *another* error union. More generally, the problem here is that `try` doesn't know when it should or shouldn't nest error unions. This occasionally broke code which looked like it should work. So, this commit prevents `try` from propagating result types through to its operand. A key motivation for the original proposal here was decl literals; so, as a special case, `try .foo(...)` is still an allowed syntax form, caught by AstGen and specially lowered. This does open the doors to allowing other special cases for decl literals in future, such as `.foo(...) catch ...`, but those proposals are for another time. Resolves: #21991 Resolves: #22633
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig16
-rw-r--r--src/print_zir.zig2
2 files changed, 0 insertions, 18 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 93b367b9d8..5c1b6a10f5 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -1257,8 +1257,6 @@ fn analyzeBodyInner(
.validate_array_init_ref_ty => try sema.zirValidateArrayInitRefTy(block, inst),
.opt_eu_base_ptr_init => try sema.zirOptEuBasePtrInit(block, inst),
.coerce_ptr_elem_ty => try sema.zirCoercePtrElemTy(block, inst),
- .try_operand_ty => try sema.zirTryOperandTy(block, inst, false),
- .try_ref_operand_ty => try sema.zirTryOperandTy(block, inst, true),
.clz => try sema.zirBitCount(block, inst, .clz, Value.clz),
.ctz => try sema.zirBitCount(block, inst, .ctz, Value.ctz),
@@ -2085,20 +2083,6 @@ fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoi
const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
cur = un_node.operand;
},
- .try_operand_ty => {
- // Either the input type was itself poison, or it was a slice, which we cannot translate
- // to an overall result type.
- const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
- const operand_ref = try sema.resolveInst(un_node.operand);
- if (operand_ref == .generic_poison_type) {
- // The input was poison -- keep looking.
- cur = un_node.operand;
- continue;
- }
- // We got a poison because the result type was a slice. This is a tricky case -- let's just
- // not bother explaining it to the user for now...
- return .unknown;
- },
.struct_init_field_type => {
const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const extra = sema.code.extraData(Zir.Inst.FieldType, pl_node.payload_index).data;
diff --git a/src/print_zir.zig b/src/print_zir.zig
index afa94f40ed..d04ef46c9f 100644
--- a/src/print_zir.zig
+++ b/src/print_zir.zig
@@ -278,8 +278,6 @@ const Writer = struct {
.opt_eu_base_ptr_init,
.restore_err_ret_index_unconditional,
.restore_err_ret_index_fn_entry,
- .try_operand_ty,
- .try_ref_operand_ty,
=> try self.writeUnNode(stream, inst),
.ref,