authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-09-09 18:51:13+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-09-09 18:51:13+02:00
logcc6376058784aa7a910e93c31ac8bd819de4e187
tree0aa35cb3c24648b2944f548a2101e20999048d92
parent2482bdf22b77bdee718167da5390157cc792dced

Allow comparison between union tag and enum literal

Closes #2810

2 files changed, 35 insertions(+), 0 deletions(-)

src/ir.cpp+25
......@@ -13228,6 +13228,31 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1322813228 ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null",
1322913229 buf_ptr(&non_null_type->name)));
1323013230 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 IrInstruction *result = ir_build_bin_op(&ira->new_irb,
13251 bin_op_instruction->base.scope, bin_op_instruction->base.source_node,
13252 op_id, casted_union, casted_val, bin_op_instruction->safety_check_on);
13253 result->value.type = ira->codegen->builtin_types.entry_bool;
13254
13255 return result;
1323113256 }
1323213257
1323313258 if (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) {
test/stage1/behavior/union.zig+10
......@@ -467,3 +467,13 @@ test "union no tag with struct member" {
467467 var u = Union{ .s = Struct{} };
468468 u.foo();
469469}
470
471test "comparison between union and enum literal" {
472 var x = Payload{.A = 42};
473 expect(x == .A);
474 expect(x != .B);
475 expect(x != .C);
476 expect((x == .B) == false);
477 expect((x == .C) == false);
478 expect((x != .A) == false);
479}