Commit 00720c52f6

Andrew Kelley <andrew@ziglang.org>
2022-06-03 04:05:53
Sema: implement try_inline
1 parent ef885a7
Changed files (1)
src/Sema.zig
@@ -1324,10 +1324,66 @@ fn analyzeBodyInner(
             },
             .@"try" => blk: {
                 if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
-                @panic("TODO");
+                const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+                const src = inst_data.src();
+                const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
+                const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
+                const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];
+                const operand = try sema.resolveInst(extra.data.operand);
+                const operand_ty = sema.typeOf(operand);
+                const is_ptr = operand_ty.zigTypeTag() == .Pointer;
+                const err_union = if (is_ptr)
+                    try sema.analyzeLoad(block, src, operand, operand_src)
+                else
+                    operand;
+                const is_non_err = try sema.analyzeIsNonErr(block, operand_src, err_union);
+                const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err);
+                if (is_non_err_tv.val.toBool()) {
+                    if (is_ptr) {
+                        break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
+                    } else {
+                        const err_union_ty = sema.typeOf(err_union);
+                        break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false);
+                    }
+                }
+                const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
+                    break always_noreturn;
+                if (inst == break_data.block_inst) {
+                    break :blk try sema.resolveInst(break_data.operand);
+                } else {
+                    break break_data.inst;
+                }
             },
-            .try_inline => {
-                @panic("TODO");
+            .try_inline => blk: {
+                const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+                const src = inst_data.src();
+                const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
+                const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
+                const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len];
+                const operand = try sema.resolveInst(extra.data.operand);
+                const operand_ty = sema.typeOf(operand);
+                const is_ptr = operand_ty.zigTypeTag() == .Pointer;
+                const err_union = if (is_ptr)
+                    try sema.analyzeLoad(block, src, operand, operand_src)
+                else
+                    operand;
+                const is_non_err = try sema.analyzeIsNonErr(block, operand_src, err_union);
+                const is_non_err_tv = try sema.resolveInstConst(block, operand_src, is_non_err);
+                if (is_non_err_tv.val.toBool()) {
+                    if (is_ptr) {
+                        break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
+                    } else {
+                        const err_union_ty = sema.typeOf(err_union);
+                        break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false);
+                    }
+                }
+                const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
+                    break always_noreturn;
+                if (inst == break_data.block_inst) {
+                    break :blk try sema.resolveInst(break_data.operand);
+                } else {
+                    break break_data.inst;
+                }
             },
         };
         if (sema.typeOf(air_inst).isNoReturn())