diff options
| author | LemonBoy <thatlemon@gmail.com> | 2019-09-09 18:51:13 +0200 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2019-09-09 18:51:13 +0200 |
| commit | cc6376058784aa7a910e93c31ac8bd819de4e187 (patch) | |
| tree | 0aa35cb3c24648b2944f548a2101e20999048d92 | |
| parent | 2482bdf22b77bdee718167da5390157cc792dced (diff) | |
| download | zig-cc6376058784aa7a910e93c31ac8bd819de4e187.tar.gz zig-cc6376058784aa7a910e93c31ac8bd819de4e187.zip | |
Allow comparison between union tag and enum literal
Closes #2810
| -rw-r--r-- | src/ir.cpp | 25 | ||||
| -rw-r--r-- | test/stage1/behavior/union.zig | 10 |
2 files changed, 35 insertions, 0 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 6b71fa8d17..bbea993162 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13228,6 +13228,31 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", buf_ptr(&non_null_type->name))); return ira->codegen->invalid_instruction; + } else if (is_equality_cmp && ( + (op1->value.type->id == ZigTypeIdEnumLiteral && op2->value.type->id == ZigTypeIdUnion) || + (op2->value.type->id == ZigTypeIdEnumLiteral && op1->value.type->id == ZigTypeIdUnion))) + { + // Support equality comparison between a union's tag value and a enum literal + IrInstruction *union_val = op1->value.type->id == ZigTypeIdUnion ? op1 : op2; + IrInstruction *enum_val = op1->value.type->id == ZigTypeIdUnion ? op2 : op1; + + ZigType *tag_type = union_val->value.type->data.unionation.tag_type; + assert(tag_type != nullptr); + + IrInstruction *casted_union = ir_implicit_cast(ira, union_val, tag_type); + if (type_is_invalid(casted_union->value.type)) + return ira->codegen->invalid_instruction; + + IrInstruction *casted_val = ir_implicit_cast(ira, enum_val, tag_type); + if (type_is_invalid(casted_val->value.type)) + return ira->codegen->invalid_instruction; + + IrInstruction *result = ir_build_bin_op(&ira->new_irb, + bin_op_instruction->base.scope, bin_op_instruction->base.source_node, + op_id, casted_union, casted_val, bin_op_instruction->safety_check_on); + result->value.type = ira->codegen->builtin_types.entry_bool; + + return result; } if (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) { diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index d28a0f8ea4..1f8ca82958 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -467,3 +467,13 @@ test "union no tag with struct member" { var u = Union{ .s = Struct{} }; u.foo(); } + +test "comparison between union and enum literal" { + var x = Payload{.A = 42}; + expect(x == .A); + expect(x != .B); + expect(x != .C); + expect((x == .B) == false); + expect((x == .C) == false); + expect((x != .A) == false); +} |
