diff --git a/src/codegen.zig b/src/codegen.zig index f978115ebcda..3e1d55575a8b 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -799,6 +799,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { .switchbr => return self.genSwitch(inst.castTag(.switchbr).?), .unreach => return MCValue{ .unreach = {} }, .unwrap_optional => return self.genUnwrapOptional(inst.castTag(.unwrap_optional).?), + .unwrap_err_err => return self.genUnwrapErrErr(inst.castTag(.unwrap_err_err).?), + .unwrap_err_payload => return self.genUnwrapErrPayload(inst.castTag(.unwrap_err_payload).?), .wrap_optional => return self.genWrapOptional(inst.castTag(.wrap_optional).?), .varptr => return self.genVarPtr(inst.castTag(.varptr).?), .xor => return self.genXor(inst.castTag(.xor).?), @@ -1051,6 +1053,23 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { } } + fn genUnwrapErrErr(self: *Self, inst: *ir.Inst.UnOp) !MCValue { + // No side effects, so if it's unreferenced, do nothing. + if (inst.base.isUnused()) + return MCValue.dead; + switch (arch) { + else => return self.fail(inst.base.src, "TODO implement unwrap error union error for {}", .{self.target.cpu.arch}), + } + } + + fn genUnwrapErrPayload(self: *Self, inst: *ir.Inst.UnOp) !MCValue { + // No side effects, so if it's unreferenced, do nothing. + if (inst.base.isUnused()) + return MCValue.dead; + switch (arch) { + else => return self.fail(inst.base.src, "TODO implement unwrap error union payload for {}", .{self.target.cpu.arch}), + } + } fn genWrapOptional(self: *Self, inst: *ir.Inst.UnOp) !MCValue { const optional_ty = inst.base.ty; diff --git a/src/ir.zig b/src/ir.zig index fc293232475e..15eef3f5f4ee 100644 --- a/src/ir.zig +++ b/src/ir.zig @@ -95,6 +95,10 @@ pub const Inst = struct { intcast, unwrap_optional, wrap_optional, + /// gets the payload of an error union + unwrap_err_payload, + /// gets the error from an error union + unwrap_err_err, xor, switchbr, @@ -120,6 +124,8 @@ pub const Inst = struct { .load, .unwrap_optional, .wrap_optional, + .unwrap_err_payload, + .unwrap_err_err, => UnOp, .add, diff --git a/src/zir.zig b/src/zir.zig index 21bd4f84355e..b63892d24a40 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -274,7 +274,7 @@ pub const Inst = struct { unwrap_optional_unsafe, /// Gets the payload of an error union unwrap_err_safe, - /// Same as previous, but without safety checks. Used for orelse, if and while + /// Same as previous, but without safety checks. Used for if, try, catch and while unwrap_err_unsafe, /// Gets the error code value of an error union unwrap_err_code, @@ -2371,6 +2371,8 @@ const EmitZIR = struct { .iserr => try self.emitUnOp(inst.src, new_body, inst.castTag(.iserr).?, .iserr), .load => try self.emitUnOp(inst.src, new_body, inst.castTag(.load).?, .deref), .ref => try self.emitUnOp(inst.src, new_body, inst.castTag(.ref).?, .ref), + .unwrap_err_payload => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_err_payload).?, .unwrap_err_unsafe), + .unwrap_err_err => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_err_err).?, .unwrap_err_code), .unwrap_optional => try self.emitUnOp(inst.src, new_body, inst.castTag(.unwrap_optional).?, .unwrap_optional_unsafe), .wrap_optional => try self.emitCast(inst.src, new_body, inst.castTag(.wrap_optional).?, .as),