Comptime folding of enum/union comparisons
parent
cc63760587
commit
4b1cd45472
15
src/ir.cpp
15
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))
|
if (type_is_invalid(casted_val->value.type))
|
||||||
return ira->codegen->invalid_instruction;
|
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,
|
IrInstruction *result = ir_build_bin_op(&ira->new_irb,
|
||||||
bin_op_instruction->base.scope, bin_op_instruction->base.source_node,
|
bin_op_instruction->base.scope, bin_op_instruction->base.source_node,
|
||||||
op_id, casted_union, casted_val, bin_op_instruction->safety_check_on);
|
op_id, casted_union, casted_val, bin_op_instruction->safety_check_on);
|
||||||
|
|
|
@ -468,7 +468,7 @@ test "union no tag with struct member" {
|
||||||
u.foo();
|
u.foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
test "comparison between union and enum literal" {
|
fn testComparison() void {
|
||||||
var x = Payload{.A = 42};
|
var x = Payload{.A = 42};
|
||||||
expect(x == .A);
|
expect(x == .A);
|
||||||
expect(x != .B);
|
expect(x != .B);
|
||||||
|
@ -477,3 +477,8 @@ test "comparison between union and enum literal" {
|
||||||
expect((x == .C) == false);
|
expect((x == .C) == false);
|
||||||
expect((x != .A) == false);
|
expect((x != .A) == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "comparison between union and enum literal" {
|
||||||
|
testComparison();
|
||||||
|
comptime testComparison();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue