aboutsummaryrefslogtreecommitdiff
path: root/src/Air.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-06-06 19:01:39 -0400
committerGitHub <noreply@github.com>2022-06-06 19:01:39 -0400
commitd1bfc83774ffaeeb7646f3003038bc4e4e94f143 (patch)
treecef9979f6d0034dcc3f99567bf12e0b7f3b643c1 /src/Air.zig
parentbe639eecc209d8039176c9750f28e8c960400fb2 (diff)
parent8ca6dc33d1523061f198474c84a68330085d6667 (diff)
downloadzig-d1bfc83774ffaeeb7646f3003038bc4e4e94f143.tar.gz
zig-d1bfc83774ffaeeb7646f3003038bc4e4e94f143.zip
Merge pull request #11783 from ziglang/stage2-try
introduce a "try" ZIR and AIR instruction
Diffstat (limited to 'src/Air.zig')
-rw-r--r--src/Air.zig33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/Air.zig b/src/Air.zig
index 5571fc6359..53421b6475 100644
--- a/src/Air.zig
+++ b/src/Air.zig
@@ -320,6 +320,20 @@ pub const Inst = struct {
/// Result type is always noreturn; no instructions in a block follow this one.
/// Uses the `pl_op` field. Operand is the condition. Payload is `SwitchBr`.
switch_br,
+ /// Given an operand which is an error union, splits control flow. In
+ /// case of error, control flow goes into the block that is part of this
+ /// instruction, which is guaranteed to end with a return instruction
+ /// and never breaks out of the block.
+ /// In the case of non-error, control flow proceeds to the next instruction
+ /// after the `try`, with the result of this instruction being the unwrapped
+ /// payload value, as if `unwrap_errunion_payload` was executed on the operand.
+ /// Uses the `pl_op` field. Payload is `Try`.
+ @"try",
+ /// Same as `try` except the operand is a pointer to an error union, and the
+ /// result is a pointer to the payload. Result is as if `unwrap_errunion_payload_ptr`
+ /// was executed on the operand.
+ /// Uses the `ty_pl` field. Payload is `TryPtr`.
+ try_ptr,
/// A comptime-known value. Uses the `ty_pl` field, payload is index of
/// `values` array.
constant,
@@ -780,6 +794,19 @@ pub const SwitchBr = struct {
};
};
+/// This data is stored inside extra. Trailing:
+/// 0. body: Inst.Index // for each body_len
+pub const Try = struct {
+ body_len: u32,
+};
+
+/// This data is stored inside extra. Trailing:
+/// 0. body: Inst.Index // for each body_len
+pub const TryPtr = struct {
+ ptr: Inst.Ref,
+ body_len: u32,
+};
+
pub const StructField = struct {
/// Whether this is a pointer or byval is determined by the AIR tag.
struct_operand: Inst.Ref,
@@ -991,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,
@@ -1102,6 +1130,11 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
const extra = air.extraData(Air.Bin, datas[inst].pl_op.payload).data;
return air.typeOf(extra.lhs);
},
+
+ .@"try" => {
+ const err_union_ty = air.typeOf(datas[inst].pl_op.operand);
+ return err_union_ty.errorUnionPayload();
+ },
}
}