diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-06-02 19:40:18 -0700 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-06-05 10:37:08 +0200 |
| commit | 6d3586e0edf3278862a3a969debaa842014f8110 (patch) | |
| tree | bcfd155cf39aebb455c36df4dbdae43a3d499baa /src | |
| parent | 00720c52f6333c314aee68de31ef505b2665e44e (diff) | |
| download | zig-6d3586e0edf3278862a3a969debaa842014f8110.tar.gz zig-6d3586e0edf3278862a3a969debaa842014f8110.zip | |
explicit "_ptr" variants of ZIR try instruction
* Introduce "_ptr" variants of ZIR try instruction to disallow constructs
such as `try` on a pointer value instead of an error union value.
* Disable the "_inline" variants of the ZIR try instruction for now because
we are out of ZIR tags. I will free up some space in an independent commit.
* AstGen: fix tryExpr calling rvalue() on ResultLoc.ref
Diffstat (limited to 'src')
| -rw-r--r-- | src/Air.zig | 2 | ||||
| -rw-r--r-- | src/AstGen.zig | 20 | ||||
| -rw-r--r-- | src/Sema.zig | 97 | ||||
| -rw-r--r-- | src/Zir.zig | 26 | ||||
| -rw-r--r-- | src/print_zir.zig | 2 |
5 files changed, 104 insertions, 43 deletions
diff --git a/src/Air.zig b/src/Air.zig index efaa7f9b6b..53421b6475 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -1018,6 +1018,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { .shl_with_overflow, .ptr_add, .ptr_sub, + .try_ptr, => return air.getRefType(datas[inst].ty_pl.ty), .not, @@ -1055,7 +1056,6 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { .popcount, .byte_swap, .bit_reverse, - .try_ptr, => return air.getRefType(datas[inst].ty_op.ty), .loop, diff --git a/src/AstGen.zig b/src/AstGen.zig index 7874ed8218..adb1223b71 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -2426,7 +2426,9 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .ret_ptr, .ret_type, .@"try", - .try_inline, + .try_ptr, + //.try_inline, + //.try_ptr_inline, => break :b false, .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) { @@ -4880,7 +4882,16 @@ fn tryExpr( // This could be a pointer or value depending on the `rl` parameter. const operand = try expr(parent_gz, scope, operand_rl, operand_node); const is_inline = parent_gz.force_comptime; - const block_tag: Zir.Inst.Tag = if (is_inline) .try_inline else .@"try"; + const is_inline_bit = @as(u2, @boolToInt(is_inline)); + const is_ptr_bit = @as(u2, @boolToInt(operand_rl == .ref)) << 1; + const block_tag: Zir.Inst.Tag = switch (is_inline_bit | is_ptr_bit) { + 0b00 => .@"try", + 0b01 => .@"try", + //0b01 => .try_inline, + 0b10 => .try_ptr, + 0b11 => .try_ptr, + //0b11 => .try_ptr_inline, + }; const try_inst = try parent_gz.makeBlockInst(block_tag, node); try parent_gz.instructions.append(astgen.gpa, try_inst); @@ -4897,7 +4908,10 @@ fn tryExpr( try else_scope.setTryBody(try_inst, operand); const result = indexToRef(try_inst); - return rvalue(parent_gz, rl, result, node); + switch (rl) { + .ref => return result, + else => return rvalue(parent_gz, rl, result, node), + } } fn orelseCatchExpr( diff --git a/src/Sema.zig b/src/Sema.zig index d2186b75db..12ff5c5dbc 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1323,28 +1323,18 @@ fn analyzeBodyInner( } }, .@"try" => blk: { - if (!block.is_comptime) break :blk try sema.zirTry(block, inst); + if (!block.is_comptime) break :blk try sema.zirTry(block, inst, false); 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 err_union = try sema.resolveInst(extra.data.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 err_union_ty = sema.typeOf(err_union); + break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); } const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse break always_noreturn; @@ -1354,28 +1344,50 @@ fn analyzeBodyInner( break break_data.inst; } }, - .try_inline => blk: { + //.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; + // } + //}, + .try_ptr => blk: { + if (!block.is_comptime) break :blk try sema.zirTry(block, inst, true); 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 err_union = try sema.analyzeLoad(block, src, operand, operand_src); 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); - } + break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); } const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse break always_noreturn; @@ -1385,6 +1397,27 @@ fn analyzeBodyInner( break break_data.inst; } }, + //.try_ptr_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 err_union = try sema.analyzeLoad(block, src, operand, operand_src); + // 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()) { + // break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, 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()) break always_noreturn; @@ -13032,15 +13065,18 @@ fn zirCondbr( return always_noreturn; } -fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Ref { +fn zirTry( + sema: *Sema, + parent_block: *Block, + inst: Zir.Inst.Index, + is_ptr: bool, +) CompileError!Zir.Inst.Ref { 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 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(parent_block, src, operand, operand_src) else @@ -13073,6 +13109,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! _ = try sema.analyzeBodyInner(&sub_block, body); if (is_ptr) { + const operand_ty = sema.typeOf(operand); const ptr_info = operand_ty.ptrInfo().data; const res_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = err_union_ty.errorUnionPayload(), diff --git a/src/Zir.zig b/src/Zir.zig index a089c4089e..02f9a97155 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -328,10 +328,14 @@ pub const Inst = struct { /// payload value, as if `err_union_payload_unsafe` was executed on the operand. /// Uses the `pl_node` union field. Payload is `Try`. @"try", - /// Same as `try` except the operand is coerced to a comptime value, and - /// only the taken branch is analyzed. The block must terminate with an "inline" - /// variant of a noreturn instruction. - try_inline, + ///// Same as `try` except the operand is coerced to a comptime value, and + ///// only the taken branch is analyzed. The block must terminate with an "inline" + ///// variant of a noreturn instruction. + //try_inline, + /// Same as `try` except the operand is a pointer and the result is a pointer. + try_ptr, + ///// Same as `try_inline` except the operand is a pointer and the result is a pointer. + //try_ptr_inline, /// An error set type definition. Contains a list of field names. /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`. error_set_decl, @@ -1245,7 +1249,9 @@ pub const Inst = struct { .ret_ptr, .ret_type, .@"try", - .try_inline, + .try_ptr, + //.try_inline, + //.try_ptr_inline, => false, .@"break", @@ -1525,7 +1531,9 @@ pub const Inst = struct { .repeat_inline, .panic, .@"try", - .try_inline, + .try_ptr, + //.try_inline, + //.try_ptr_inline, => false, .extended => switch (data.extended.opcode) { @@ -1587,7 +1595,9 @@ pub const Inst = struct { .condbr = .pl_node, .condbr_inline = .pl_node, .@"try" = .pl_node, - .try_inline = .pl_node, + .try_ptr = .pl_node, + //.try_inline = .pl_node, + //.try_ptr_inline = .pl_node, .error_set_decl = .pl_node, .error_set_decl_anon = .pl_node, .error_set_decl_func = .pl_node, @@ -3766,7 +3776,7 @@ fn findDeclsInner( try zir.findDeclsBody(list, then_body); try zir.findDeclsBody(list, else_body); }, - .@"try", .try_inline => { + .@"try", .try_ptr => { const inst_data = datas[inst].pl_node; const extra = zir.extraData(Inst.Try, inst_data.payload_index); const body = zir.extra[extra.end..][0..extra.data.body_len]; diff --git a/src/print_zir.zig b/src/print_zir.zig index 04289aa955..3257a3cb58 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -381,7 +381,7 @@ const Writer = struct { => try self.writeCondBr(stream, inst), .@"try", - .try_inline, + .try_ptr, => try self.writeTry(stream, inst), .error_set_decl => try self.writeErrorSetDecl(stream, inst, .parent), |
