Commit 271a37b418

Andrew Kelley <superjoe30@gmail.com>
2016-05-07 04:49:28
implicit wrap widening cast on integer peer types
closes #46
1 parent 6131b37
Changed files (3)
src/analyze.cpp
@@ -1892,12 +1892,25 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa
             continue;
         } else if (prev_type->id == TypeTableEntryIdInt &&
                    cur_type->id == TypeTableEntryIdInt &&
-                   prev_type->data.integral.is_signed == cur_type->data.integral.is_signed)
+                   prev_type->data.integral.is_signed == cur_type->data.integral.is_signed &&
+                   (cur_type->data.integral.bit_count >= prev_type->data.integral.bit_count &&
+                    (cur_type->data.integral.is_wrapping || !prev_type->data.integral.is_wrapping)))
         {
             if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) {
                 prev_type = cur_type;
                 prev_node = cur_node;
+            } else if (cur_type->data.integral.is_wrapping && !prev_type->data.integral.is_wrapping) {
+                prev_type = cur_type;
+                prev_node = cur_node;
             }
+            continue;
+        } else if (prev_type->id == TypeTableEntryIdInt &&
+                   cur_type->id == TypeTableEntryIdInt &&
+                   prev_type->data.integral.is_signed == cur_type->data.integral.is_signed &&
+                   (prev_type->data.integral.bit_count >= cur_type->data.integral.bit_count &&
+                    (prev_type->data.integral.is_wrapping || !cur_type->data.integral.is_wrapping)))
+        {
+            continue;
         } else if (prev_type->id == TypeTableEntryIdFloat &&
                    cur_type->id == TypeTableEntryIdFloat)
         {
test/run_tests.cpp
@@ -1354,6 +1354,13 @@ fn mul(a: u16, b: u16) -> u16 {
             ".tmp_source.zig:5:1: error: function evaluation caused overflow",
             ".tmp_source.zig:3:18: note: called from here",
             ".tmp_source.zig:6:7: note: overflow occurred here");
+
+    add_compile_fail_case("add incompatible int types", R"SOURCE(
+fn add(x: i8w, y: i32) {
+    const z = x + y;
+}
+    )SOURCE", 1, ".tmp_source.zig:3:17: error: incompatible types: 'i8w' and 'i32'");
+
 }
 
 //////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig
@@ -1534,3 +1534,20 @@ fn shl_with_overflow() {
     assert(!@shl_with_overflow(u16, 0b0010111111111111, 2, &result));
     assert(result == 0b1011111111111100);
 }
+
+#attribute("test")
+fn combine_non_wrap_with_wrap() {
+    const x: i32 = 123;
+    const y: i32w = 456;
+    const z = x + y;
+    const z2 = y + x;
+    assert(@typeof(z) == i32w);
+    assert(@typeof(z2) == i32w);
+
+    const a: i8 = 123;
+    const b: i32w = 456;
+    const c = b + a;
+    const d = a + b;
+    assert(@typeof(c) == i32w);
+    assert(@typeof(d) == i32w);
+}