Created
April 15, 2020 02:15
-
-
Save mikdusan/371fdf4b327671d7e0c332303d12bb51 to your computer and use it in GitHub Desktop.
some progress on #1332
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/CMakeLists.txt b/CMakeLists.txt | |
index 27bc6a04f..f9e336295 100644 | |
--- a/CMakeLists.txt | |
+++ b/CMakeLists.txt | |
@@ -329,6 +329,9 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") | |
set(EXE_CFLAGS "${EXE_CFLAGS} /w") | |
else() | |
set(EXE_CFLAGS "${EXE_CFLAGS} -Werror -Wall -Werror=implicit-fallthrough") | |
+ set(EXE_CFLAGS "${EXE_CFLAGS} -fcolor-diagnostics") | |
+ set(EXE_CFLAGS "${EXE_CFLAGS} -Wno-error=unused-variable") | |
+ set(EXE_CFLAGS "${EXE_CFLAGS} -Wno-error=unused-label") | |
endif() | |
endif() | |
diff --git a/src/ir.cpp b/src/ir.cpp | |
index b9438dda3..04c84150b 100644 | |
--- a/src/ir.cpp | |
+++ b/src/ir.cpp | |
@@ -16394,6 +16394,82 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i | |
IrBinOp op_id = bin_op_instruction->op_id; | |
bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); | |
+ | |
+#if 1 // TODO: mike | |
+ // unwrap_equality_operands: (?T == ?T) and combinations | |
+ if (is_equality_cmp && | |
+ op1->value->type->id != ZigTypeIdNull && | |
+ op2->value->type->id != ZigTypeIdNull) | |
+ { | |
+ if (instr_is_comptime(op1) && instr_is_comptime(op2)) { | |
+ for (;;) { | |
+ bool repeat = false; | |
+ | |
+ if (op1->value->type->id == ZigTypeIdOptional) { | |
+ if (optional_value_is_null(op1->value)) { | |
+ bool answer = (op2->value->type->id == ZigTypeIdOptional && optional_value_is_null(op2->value)) | |
+ ? true : false; | |
+ return ir_const_bool(ira, &bin_op_instruction->base.base, answer); | |
+ } | |
+ | |
+ ZigValue *tmp = ir_resolve_const(ira, op1, UndefBad); | |
+ if (!tmp) | |
+ return ira->codegen->invalid_inst_gen; | |
+ op1->value = tmp->data.x_optional; | |
+ repeat = true; | |
+// op1->dump(); | |
+ } | |
+ | |
+ if (op2->value->type->id == ZigTypeIdOptional) { | |
+ if (optional_value_is_null(op2->value)) { | |
+ bool answer = (op1->value->type->id == ZigTypeIdOptional && optional_value_is_null(op1->value)) | |
+ ? true : false; | |
+ return ir_const_bool(ira, &bin_op_instruction->base.base, answer); | |
+ } | |
+ | |
+ ZigValue *tmp = ir_resolve_const(ira, op2, UndefBad); | |
+ if (!tmp) | |
+ return ira->codegen->invalid_inst_gen; | |
+ op2->value = tmp->data.x_optional; | |
+ repeat = true; | |
+// op2->dump(); | |
+ } | |
+ | |
+ if (!repeat) break; | |
+ } | |
+ } else for (;;) { | |
+ bool repeat = false; | |
+ | |
+ if (op1->value->type->id == ZigTypeIdOptional) { | |
+ IrInstGen *op1_ref = ir_get_ref(ira, &op1->base, op1, true, false); | |
+ ZigType *op1_child_ptr_type = get_pointer_to_type_extra(ira->codegen, | |
+ op1->value->type->data.maybe.child_type, true, false, | |
+ PtrLenSingle, 0, 0, 0, false); | |
+ | |
+ IrInstGen *op1_unwrap_ptr = ir_build_optional_unwrap_ptr_gen(ira, &op1->base, op1_ref, | |
+ false, false, op1_child_ptr_type); | |
+ op1 = ir_get_deref(ira, &op1->base, op1_unwrap_ptr, nullptr); | |
+ repeat = true; | |
+// op1->dump(); | |
+ } | |
+ | |
+ if (op2->value->type->id == ZigTypeIdOptional) { | |
+ IrInstGen *op2_ref = ir_get_ref(ira, &op2->base, op2, true, false); | |
+ ZigType *op2_child_ptr_type = get_pointer_to_type_extra(ira->codegen, | |
+ op2->value->type->data.maybe.child_type, true, false, | |
+ PtrLenSingle, 0, 0, 0, false); | |
+ IrInstGen *op2_unwrap_ptr = ir_build_optional_unwrap_ptr_gen(ira, &op2->base, op2_ref, | |
+ false, false, op2_child_ptr_type); | |
+ op2 = ir_get_deref(ira, &op2->base, op2_unwrap_ptr, nullptr); | |
+ repeat = true; | |
+// op2->dump(); | |
+ } | |
+ | |
+ if (!repeat) break; | |
+ } | |
+ } | |
+#endif | |
+ | |
if (is_equality_cmp && op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdNull) { | |
return ir_const_bool(ira, &bin_op_instruction->base.base, (op_id == IrBinOpCmpEq)); | |
} else if (is_equality_cmp && | |
diff --git a/test/stage1/behavior/optional.zig b/test/stage1/behavior/optional.zig | |
index 7dd48769d..5f7af65c8 100644 | |
--- a/test/stage1/behavior/optional.zig | |
+++ b/test/stage1/behavior/optional.zig | |
@@ -198,3 +198,63 @@ test "0-bit child type coerced to optional" { | |
S.doTheTest(); | |
comptime S.doTheTest(); | |
} | |
+ | |
+test "unwrap equality operands" { | |
+ const S = struct { | |
+ fn doTheTest() void { | |
+ var i: u32 = 11; | |
+ var oi: ?u32 = 11; | |
+ var ooi: ??u32 = 11; | |
+ | |
+ var j: u32 = 11; | |
+ var oj: ?u32 = 11; | |
+ var ooj: ??u32 = 11; | |
+ | |
+ var k: u32 = 22; | |
+ var ok: ?u32 = 22; | |
+ var ook: ??u32 = 22; | |
+ | |
+ expect(i == oj); | |
+ expect(i == ooj); | |
+ expect(oj == i); | |
+ expect(ooj == i); | |
+ expect(oi == oj); | |
+ expect(oi == ooj); | |
+ expect(ooi == ooj); | |
+ | |
+ expect(i != ok); | |
+ expect(i != ook); | |
+ expect(ok != i); | |
+ expect(ook != i); | |
+ expect(oi != ok); | |
+ expect(oi != ook); | |
+ expect(ooi != ook); | |
+ | |
+ var oin: ?u32 = null; | |
+ var ooin: ??u32 = null; | |
+ var ojn: ?u32 = null; | |
+ var oojn: ??u32 = null; | |
+ | |
+ expect(oi != ojn); | |
+ expect(oin == ojn); | |
+ expect(oj != oin); | |
+ expect(ojn == oin); | |
+ | |
+ expect(i == 11); | |
+ expect(11 == i); | |
+ expect(oi == 11); | |
+ expect(11 == oi); | |
+ expect(ooi == 11); | |
+ expect(11 == ooi); | |
+ | |
+ expect(i != 22); | |
+ expect(22 != i); | |
+ expect(oi != 22); | |
+ expect(22 != oi); | |
+ expect(ooi != 22); | |
+ expect(22 != ooi); | |
+ } | |
+ }; | |
+ S.doTheTest(); | |
+ comptime S.doTheTest(); | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment