authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-06-17 10:28:42-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-06-17 10:29:04-04:00
log1566ca21c4bbe7f5aa5f385c7ebc22c780e54c8f
tree49ceed12fda4c4c126458500da947a62fde93615
parent91afdc58d2380556ecacf8bddb949dd905e67c86

fix peer type resolution for array and error

closes #388

2 files changed, 33 insertions(+), 1 deletions(-)

src/ir.cpp+9-1
......@@ -6460,6 +6460,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
64606460 prev_inst = cur_inst;
64616461 continue;
64626462 } else if (cur_type->id == TypeTableEntryIdPureError) {
6463 if (prev_type->id == TypeTableEntryIdArray) {
6464 convert_to_const_slice = true;
6465 }
64636466 any_are_pure_error = true;
64646467 continue;
64656468 } else if (cur_type->id == TypeTableEntryIdNullLit) {
......@@ -6568,7 +6571,12 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
65686571 }
65696572 if (convert_to_const_slice) {
65706573 assert(prev_inst->value.type->id == TypeTableEntryIdArray);
6571 return get_slice_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
6574 TypeTableEntry *slice_type = get_slice_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
6575 if (any_are_pure_error) {
6576 return get_error_type(ira->codegen, slice_type);
6577 } else {
6578 return slice_type;
6579 }
65726580 } else if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) {
65736581 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||
65746582 prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)
test/cases/cast.zig+24
......@@ -227,3 +227,27 @@ test "var args implicitly casts by value arg to const ref" {
227227fn foo(args: ...) {
228228 assert(@typeOf(args[0]) == &const [5]u8);
229229}
230
231
232test "peer type resolution: error and [N]T" {
233 assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
234 comptime assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
235
236 assert(mem.eql(u8, %%testPeerErrorAndArray2(1), "OKK"));
237 comptime assert(mem.eql(u8, %%testPeerErrorAndArray2(1), "OKK"));
238}
239
240error BadValue;
241fn testPeerErrorAndArray(x: u8) -> %[]const u8 {
242 switch (x) {
243 0x00 => "OK",
244 else => error.BadValue,
245 }
246}
247fn testPeerErrorAndArray2(x: u8) -> %[]const u8 {
248 switch (x) {
249 0x00 => "OK",
250 0x01 => "OKK",
251 else => error.BadValue,
252 }
253}