| ... | ... | @@ -13228,6 +13228,46 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * |
| 13228 | 13228 | ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", |
| 13229 | 13229 | buf_ptr(&non_null_type->name))); |
| 13230 | 13230 | return ira->codegen->invalid_instruction; |
| 13231 | } else if (is_equality_cmp && ( |
| 13232 | (op1->value.type->id == ZigTypeIdEnumLiteral && op2->value.type->id == ZigTypeIdUnion) || |
| 13233 | (op2->value.type->id == ZigTypeIdEnumLiteral && op1->value.type->id == ZigTypeIdUnion))) |
| 13234 | { |
| 13235 | // Support equality comparison between a union's tag value and a enum literal |
| 13236 | IrInstruction *union_val = op1->value.type->id == ZigTypeIdUnion ? op1 : op2; |
| 13237 | IrInstruction *enum_val = op1->value.type->id == ZigTypeIdUnion ? op2 : op1; |
| 13238 | |
| 13239 | ZigType *tag_type = union_val->value.type->data.unionation.tag_type; |
| 13240 | assert(tag_type != nullptr); |
| 13241 | |
| 13242 | IrInstruction *casted_union = ir_implicit_cast(ira, union_val, tag_type); |
| 13243 | if (type_is_invalid(casted_union->value.type)) |
| 13244 | return ira->codegen->invalid_instruction; |
| 13245 | |
| 13246 | IrInstruction *casted_val = ir_implicit_cast(ira, enum_val, tag_type); |
| 13247 | if (type_is_invalid(casted_val->value.type)) |
| 13248 | return ira->codegen->invalid_instruction; |
| 13249 | |
| 13250 | if (instr_is_comptime(casted_union)) { |
| 13251 | ConstExprValue *const_union_val = ir_resolve_const(ira, casted_union, UndefBad); |
| 13252 | if (!const_union_val) |
| 13253 | return ira->codegen->invalid_instruction; |
| 13254 | |
| 13255 | ConstExprValue *const_enum_val = ir_resolve_const(ira, casted_val, UndefBad); |
| 13256 | if (!const_enum_val) |
| 13257 | return ira->codegen->invalid_instruction; |
| 13258 | |
| 13259 | Cmp cmp_result = bigint_cmp(&const_union_val->data.x_union.tag, &const_enum_val->data.x_enum_tag); |
| 13260 | bool bool_result = (op_id == IrBinOpCmpEq) ? cmp_result == CmpEQ : cmp_result != CmpEQ; |
| 13261 | |
| 13262 | return ir_const_bool(ira, &bin_op_instruction->base, bool_result); |
| 13263 | } |
| 13264 | |
| 13265 | IrInstruction *result = ir_build_bin_op(&ira->new_irb, |
| 13266 | bin_op_instruction->base.scope, bin_op_instruction->base.source_node, |
| 13267 | op_id, casted_union, casted_val, bin_op_instruction->safety_check_on); |
| 13268 | result->value.type = ira->codegen->builtin_types.entry_bool; |
| 13269 | |
| 13270 | return result; |
| 13231 | 13271 | } |
| 13232 | 13272 | |
| 13233 | 13273 | if (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) { |