diff options
| author | LemonBoy <thatlemon@gmail.com> | 2019-09-09 19:09:56 +0200 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2019-09-09 19:09:56 +0200 |
| commit | 4b1cd45472cab5569438fef018990fbe8043c6c3 (patch) | |
| tree | ae1f233ad992910d92b3882202cda30808491d4e | |
| parent | cc6376058784aa7a910e93c31ac8bd819de4e187 (diff) | |
| download | zig-4b1cd45472cab5569438fef018990fbe8043c6c3.tar.gz zig-4b1cd45472cab5569438fef018990fbe8043c6c3.zip | |
Comptime folding of enum/union comparisons
| -rw-r--r-- | src/ir.cpp | 15 | ||||
| -rw-r--r-- | test/stage1/behavior/union.zig | 7 |
2 files changed, 21 insertions, 1 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index bbea993162..196e84eead 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13247,6 +13247,21 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * if (type_is_invalid(casted_val->value.type)) return ira->codegen->invalid_instruction; + if (instr_is_comptime(casted_union)) { + ConstExprValue *const_union_val = ir_resolve_const(ira, casted_union, UndefBad); + if (!const_union_val) + return ira->codegen->invalid_instruction; + + ConstExprValue *const_enum_val = ir_resolve_const(ira, casted_val, UndefBad); + if (!const_enum_val) + return ira->codegen->invalid_instruction; + + Cmp cmp_result = bigint_cmp(&const_union_val->data.x_union.tag, &const_enum_val->data.x_enum_tag); + bool bool_result = (op_id == IrBinOpCmpEq) ? cmp_result == CmpEQ : cmp_result != CmpEQ; + + return ir_const_bool(ira, &bin_op_instruction->base, bool_result); + } + 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); diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index 1f8ca82958..7c5c653275 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -468,7 +468,7 @@ test "union no tag with struct member" { u.foo(); } -test "comparison between union and enum literal" { +fn testComparison() void { var x = Payload{.A = 42}; expect(x == .A); expect(x != .B); @@ -477,3 +477,8 @@ test "comparison between union and enum literal" { expect((x == .C) == false); expect((x != .A) == false); } + +test "comparison between union and enum literal" { + testComparison(); + comptime testComparison(); +} |
