| ... | ... | @@ -1736,6 +1736,8 @@ pub const DeclGen = struct { |
| 1736 | 1736 | |
| 1737 | 1737 | .is_null => try self.airIsNull(inst, .is_null), |
| 1738 | 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 | 1742 | .optional_payload => try self.airUnwrapOptional(inst), |
| 1741 | 1743 | .wrap_optional => try self.airWrapOptional(inst), |
| ... | ... | @@ -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 | 3317 | fn airUnwrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 3280 | 3318 | if (self.liveness.isUnused(inst)) return null; |
| 3281 | 3319 | |