authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-28 16:27:31+02:00
committergravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-04-28 16:27:31+02:00
log2fc34eaa581cc31827e978fbd973bf36d2c647e2
treed4123e07f42b89ee8fe829066bbca0cdaff514a0
parent3178528335cb5efbf237cecb9ea9eb3bfa31b21f

Functions with infered error set can now return literals

fixes #852

3 files changed, 58 insertions(+), 18 deletions(-)

src/analyze.cpp-1
......@@ -6131,4 +6131,3 @@ bool type_can_fail(TypeTableEntry *type_entry) {
61316131bool fn_type_can_fail(FnTypeId *fn_type_id) {
61326132 return type_can_fail(fn_type_id->return_type) || fn_type_id->cc == CallingConventionAsync;
61336133}
6134
src/ir.cpp+19-17
......@@ -8111,7 +8111,7 @@ static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *
81118111 *errors = reallocate(*errors, old_errors_count, *errors_count);
81128112}
81138113
8114static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, IrInstruction **instructions, size_t instruction_count) {
8114static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, TypeTableEntry *expected_type, IrInstruction **instructions, size_t instruction_count) {
81158115 assert(instruction_count >= 1);
81168116 IrInstruction *prev_inst = instructions[0];
81178117 if (type_is_invalid(prev_inst->value.type)) {
......@@ -8158,16 +8158,6 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
81588158 continue;
81598159 }
81608160
8161 if (prev_type->id == TypeTableEntryIdNullLit) {
8162 prev_inst = cur_inst;
8163 continue;
8164 }
8165
8166 if (cur_type->id == TypeTableEntryIdNullLit) {
8167 any_are_null = true;
8168 continue;
8169 }
8170
81718161 if (prev_type->id == TypeTableEntryIdErrorSet) {
81728162 assert(err_set_type != nullptr);
81738163 if (cur_type->id == TypeTableEntryIdErrorSet) {
......@@ -8427,6 +8417,16 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
84278417 }
84288418 }
84298419
8420 if (prev_type->id == TypeTableEntryIdNullLit) {
8421 prev_inst = cur_inst;
8422 continue;
8423 }
8424
8425 if (cur_type->id == TypeTableEntryIdNullLit) {
8426 any_are_null = true;
8427 continue;
8428 }
8429
84308430 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node).id == ConstCastResultIdOk) {
84318431 continue;
84328432 }
......@@ -8610,6 +8610,10 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
86108610 } else if (err_set_type != nullptr) {
86118611 if (prev_inst->value.type->id == TypeTableEntryIdErrorSet) {
86128612 return err_set_type;
8613 } else if (prev_inst->value.type->id == TypeTableEntryIdErrorUnion) {
8614 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type->data.error_union.payload_type);
8615 } else if (expected_type != nullptr && expected_type->id == TypeTableEntryIdErrorUnion) {
8616 return get_error_union_type(ira->codegen, err_set_type, expected_type->data.error_union.payload_type);
86138617 } else {
86148618 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||
86158619 prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)
......@@ -8621,8 +8625,6 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
86218625 ir_add_error_node(ira, source_node,
86228626 buf_sprintf("unable to make error union out of null literal"));
86238627 return ira->codegen->builtin_types.entry_invalid;
8624 } else if (prev_inst->value.type->id == TypeTableEntryIdErrorUnion) {
8625 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type->data.error_union.payload_type);
86268628 } else {
86278629 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type);
86288630 }
......@@ -10645,7 +10647,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
1064510647 }
1064610648
1064710649 IrInstruction *instructions[] = {op1, op2};
10648 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, source_node, instructions, 2);
10650 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2);
1064910651 if (type_is_invalid(resolved_type))
1065010652 return resolved_type;
1065110653 type_ensure_zero_bits_known(ira->codegen, resolved_type);
......@@ -11035,7 +11037,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
1103511037 IrInstruction *op1 = bin_op_instruction->op1->other;
1103611038 IrInstruction *op2 = bin_op_instruction->op2->other;
1103711039 IrInstruction *instructions[] = {op1, op2};
11038 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, instructions, 2);
11040 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, nullptr, instructions, 2);
1103911041 if (type_is_invalid(resolved_type))
1104011042 return resolved_type;
1104111043 IrBinOp op_id = bin_op_instruction->op_id;
......@@ -13004,7 +13006,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
1300413006 return first_value->value.type;
1300513007 }
1300613008
13007 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node,
13009 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr,
1300813010 new_incoming_values.items, new_incoming_values.length);
1300913011 if (type_is_invalid(resolved_type))
1301013012 return resolved_type;
......@@ -18696,7 +18698,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
1869618698 } else if (ira->src_implicit_return_type_list.length == 0) {
1869718699 return codegen->builtin_types.entry_unreachable;
1869818700 } else {
18699 return ir_resolve_peer_types(ira, expected_type_source_node, ira->src_implicit_return_type_list.items,
18701 return ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items,
1870018702 ira->src_implicit_return_type_list.length);
1870118703 }
1870218704}
test/cases/error.zig+39
......@@ -202,3 +202,42 @@ const Error = error{};
202202fn foo3(b: usize) Error!usize {
203203 return b;
204204}
205
206
207test "error: Infer error set from literals" {
208 _ = nullLiteral("n") catch |err| handleErrors(err);
209 _ = floatLiteral("n") catch |err| handleErrors(err);
210 _ = intLiteral("n") catch |err| handleErrors(err);
211 _ = comptime nullLiteral("n") catch |err| handleErrors(err);
212 _ = comptime floatLiteral("n") catch |err| handleErrors(err);
213 _ = comptime intLiteral("n") catch |err| handleErrors(err);
214}
215
216fn handleErrors(err: var) noreturn {
217 switch (err) {
218 error.T => {}
219 }
220
221 unreachable;
222}
223
224fn nullLiteral(str: []const u8) !?i64 {
225 if (str[0] == 'n')
226 return null;
227
228 return error.T;
229}
230
231fn floatLiteral(str: []const u8) !?f64 {
232 if (str[0] == 'n')
233 return 1.0;
234
235 return error.T;
236}
237
238fn intLiteral(str: []const u8) !?i64 {
239 if (str[0] == 'n')
240 return 1;
241
242 return error.T;
243}