| ... | @@ -1736,6 +1736,8 @@ pub const DeclGen = struct { | ... | @@ -1736,6 +1736,8 @@ pub const DeclGen = struct { |
| 1736 | | 1736 | |
| 1737 | .is_null => try self.airIsNull(inst, .is_null), | 1737 | .is_null => try self.airIsNull(inst, .is_null), |
| 1738 | .is_non_null => try self.airIsNull(inst, .is_non_null), | 1738 | .is_non_null => try self.airIsNull(inst, .is_non_null), |
| | 1739 | .is_err => try self.airIsErr(inst, .is_err), |
| | 1740 | .is_non_err => try self.airIsErr(inst, .is_non_err), |
| 1739 | | 1741 | |
| 1740 | .optional_payload => try self.airUnwrapOptional(inst), | 1742 | .optional_payload => try self.airUnwrapOptional(inst), |
| 1741 | .wrap_optional => try self.airWrapOptional(inst), | 1743 | .wrap_optional => try self.airWrapOptional(inst), |
| ... | @@ -3276,6 +3278,42 @@ pub const DeclGen = struct { | ... | @@ -3276,6 +3278,42 @@ pub const DeclGen = struct { |
| 3276 | }; | 3278 | }; |
| 3277 | } | 3279 | } |
| 3278 | | 3280 | |
| | 3281 | fn airIsErr(self: *DeclGen, inst: Air.Inst.Index, pred: enum { is_err, is_non_err }) !?IdRef { |
| | 3282 | if (self.liveness.isUnused(inst)) return null; |
| | 3283 | |
| | 3284 | const mod = self.module; |
| | 3285 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| | 3286 | const operand_id = try self.resolve(un_op); |
| | 3287 | const err_union_ty = self.typeOf(un_op); |
| | 3288 | |
| | 3289 | if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) { |
| | 3290 | return try self.constBool(pred == .is_non_err, .direct); |
| | 3291 | } |
| | 3292 | |
| | 3293 | const payload_ty = err_union_ty.errorUnionPayload(mod); |
| | 3294 | const eu_layout = self.errorUnionLayout(payload_ty); |
| | 3295 | const bool_ty_ref = try self.resolveType(Type.bool, .direct); |
| | 3296 | const err_ty_ref = try self.resolveType(Type.anyerror, .direct); |
| | 3297 | |
| | 3298 | const error_id = if (!eu_layout.payload_has_bits) |
| | 3299 | operand_id |
| | 3300 | else |
| | 3301 | try self.extractField(Type.anyerror, operand_id, eu_layout.errorFieldIndex()); |
| | 3302 | |
| | 3303 | const result_id = self.spv.allocId(); |
| | 3304 | const operands = .{ |
| | 3305 | .id_result_type = self.typeId(bool_ty_ref), |
| | 3306 | .id_result = result_id, |
| | 3307 | .operand_1 = error_id, |
| | 3308 | .operand_2 = try self.constInt(err_ty_ref, 0), |
| | 3309 | }; |
| | 3310 | switch (pred) { |
| | 3311 | .is_err => try self.func.body.emit(self.spv.gpa, .OpINotEqual, operands), |
| | 3312 | .is_non_err => try self.func.body.emit(self.spv.gpa, .OpIEqual, operands), |
| | 3313 | } |
| | 3314 | return result_id; |
| | 3315 | } |
| | 3316 | |
| 3279 | fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3317 | fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3280 | if (self.liveness.isUnused(inst)) return null; | 3318 | if (self.liveness.isUnused(inst)) return null; |
| 3281 | | 3319 | |