aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-06-02 19:05:53 -0700
committerJakub Konka <kubkon@jakubkonka.com>2022-06-05 10:37:08 +0200
commit00720c52f6333c314aee68de31ef505b2665e44e (patch)
tree6801a33464f65f279a2034dc2707db0c70392f32 /src
parentef885a78d606693c73641159731274cc57f6ea98 (diff)
downloadzig-00720c52f6333c314aee68de31ef505b2665e44e.tar.gz
zig-00720c52f6333c314aee68de31ef505b2665e44e.zip
Sema: implement try_inline
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig62
1 files changed, 59 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index de4b6c4236..d2186b75db 100644
--- a/src/Sema.zig
+++ b/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())