Commit 1566ca21c4

Andrew Kelley <superjoe30@gmail.com>
2017-06-17 16:28:42
fix peer type resolution for array and error
closes #388
1 parent 91afdc5
Changed files (2)
src
test
cases
src/ir.cpp
@@ -6460,6 +6460,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
             prev_inst = cur_inst;
             continue;
         } else if (cur_type->id == TypeTableEntryIdPureError) {
+            if (prev_type->id == TypeTableEntryIdArray) {
+                convert_to_const_slice = true;
+            }
             any_are_pure_error = true;
             continue;
         } else if (cur_type->id == TypeTableEntryIdNullLit) {
@@ -6568,7 +6571,12 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
     }
     if (convert_to_const_slice) {
         assert(prev_inst->value.type->id == TypeTableEntryIdArray);
-        return get_slice_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
+        TypeTableEntry *slice_type = get_slice_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
+        if (any_are_pure_error) {
+            return get_error_type(ira->codegen, slice_type);
+        } else {
+            return slice_type;
+        }
     } else if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) {
         if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||
             prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)
test/cases/cast.zig
@@ -227,3 +227,27 @@ test "var args implicitly casts by value arg to const ref" {
 fn foo(args: ...) {
     assert(@typeOf(args[0]) == &const [5]u8);
 }
+
+
+test "peer type resolution: error and [N]T" {
+    assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
+    comptime assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
+
+    assert(mem.eql(u8, %%testPeerErrorAndArray2(1), "OKK"));
+    comptime assert(mem.eql(u8, %%testPeerErrorAndArray2(1), "OKK"));
+}
+
+error BadValue;
+fn testPeerErrorAndArray(x: u8) -> %[]const u8 {
+    switch (x) {
+        0x00 => "OK",
+        else => error.BadValue,
+    }
+}
+fn testPeerErrorAndArray2(x: u8) -> %[]const u8 {
+    switch (x) {
+        0x00 => "OK",
+        0x01 => "OKK",
+        else => error.BadValue,
+    }
+}