Commit 867686af42

Andrew Kelley <superjoe30@gmail.com>
2017-01-16 22:07:03
equality comparison of void types is known at compile time
closes #56
1 parent fdbc2d8
Changed files (2)
src/ir.cpp
@@ -94,8 +94,12 @@ static Buf *exec_c_import_buf(IrExecutable *exec) {
     return exec->c_import_buf;
 }
 
+static bool value_is_comptime(ConstExprValue *const_val) {
+    return const_val->special != ConstValSpecialRuntime;
+}
+
 static bool instr_is_comptime(IrInstruction *instruction) {
-    return instruction->value.special != ConstValSpecialRuntime;
+    return value_is_comptime(&instruction->value);
 }
 
 static bool instr_is_unreachable(IrInstruction *instruction) {
@@ -6907,7 +6911,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
 
     ConstExprValue *op1_val = &casted_op1->value;
     ConstExprValue *op2_val = &casted_op2->value;
-    if (op1_val->special != ConstValSpecialRuntime && op2_val->special != ConstValSpecialRuntime) {
+    if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) {
         bool type_can_gt_lt_cmp = (resolved_type->id == TypeTableEntryIdNumLitFloat ||
                 resolved_type->id == TypeTableEntryIdNumLitInt ||
                 resolved_type->id == TypeTableEntryIdFloat ||
@@ -6933,7 +6937,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
 
             answer = bignum_cmp(&op1_val->data.x_bignum, &op2_val->data.x_bignum);
         } else {
-            bool are_equal = const_values_equal(op1_val, op2_val);
+            bool are_equal = resolved_type->id == TypeTableEntryIdVoid || const_values_equal(op1_val, op2_val);
             if (op_id == IrBinOpCmpEq) {
                 answer = are_equal;
             } else if (op_id == IrBinOpCmpNotEq) {
test/run_tests.cpp
@@ -1605,6 +1605,25 @@ fn derp() {
 }
     )SOURCE", 1, ".tmp_source.zig:7:13: error: cannot assign to constant");
 
+    add_compile_fail_case("compare void with void is compile time known", R"SOURCE(
+const Foo = struct {
+    a: void,
+    b: i32,
+    c: void,
+};
+
+fn f() {
+    const foo = Foo {
+        .a = {},
+        .b = 1,
+        .c = {},
+    };
+    if (foo.a != {}) {
+        @unreachable();
+    }
+}
+    )SOURCE", 1, ".tmp_source.zig:14:15: error: condition is always false; unnecessary if statement");
+
 }
 
 //////////////////////////////////////////////////////////////////////////////