aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-06-02 19:40:18 -0700
committerJakub Konka <kubkon@jakubkonka.com>2022-06-05 10:37:08 +0200
commit6d3586e0edf3278862a3a969debaa842014f8110 (patch)
treebcfd155cf39aebb455c36df4dbdae43a3d499baa /src
parent00720c52f6333c314aee68de31ef505b2665e44e (diff)
downloadzig-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.zig2
-rw-r--r--src/AstGen.zig20
-rw-r--r--src/Sema.zig97
-rw-r--r--src/Zir.zig26
-rw-r--r--src/print_zir.zig2
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),