fix peer type resolution for array and error

closes #388
This commit is contained in:
Andrew Kelley 2017-06-17 10:28:42 -04:00
parent 91afdc58d2
commit 1566ca21c4
2 changed files with 33 additions and 1 deletions

View File

@ -6460,6 +6460,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
prev_inst = cur_inst; prev_inst = cur_inst;
continue; continue;
} else if (cur_type->id == TypeTableEntryIdPureError) { } else if (cur_type->id == TypeTableEntryIdPureError) {
if (prev_type->id == TypeTableEntryIdArray) {
convert_to_const_slice = true;
}
any_are_pure_error = true; any_are_pure_error = true;
continue; continue;
} else if (cur_type->id == TypeTableEntryIdNullLit) { } 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) { if (convert_to_const_slice) {
assert(prev_inst->value.type->id == TypeTableEntryIdArray); 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) { } else if (any_are_pure_error && prev_inst->value.type->id != TypeTableEntryIdPureError) {
if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt || if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||
prev_inst->value.type->id == TypeTableEntryIdNumLitFloat) prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)

View File

@ -227,3 +227,27 @@ test "var args implicitly casts by value arg to const ref" {
fn foo(args: ...) { fn foo(args: ...) {
assert(@typeOf(args[0]) == &const [5]u8); 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,
}
}