diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-06-02 19:05:53 -0700 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-06-05 10:37:08 +0200 |
| commit | 00720c52f6333c314aee68de31ef505b2665e44e (patch) | |
| tree | 6801a33464f65f279a2034dc2707db0c70392f32 /src | |
| parent | ef885a78d606693c73641159731274cc57f6ea98 (diff) | |
| download | zig-00720c52f6333c314aee68de31ef505b2665e44e.tar.gz zig-00720c52f6333c314aee68de31ef505b2665e44e.zip | |
Sema: implement try_inline
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 62 |
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()) |
