authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-02 14:26:14-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-02 14:26:14-05:00
log39d5f44863aafa77163b2a7e32f2553a589dbb2c
tree43a0d9684bde2bb94bca491ab3718408dc05c7ed
parentcfb2c676925d77887e46631dcafa783e6c65e61d

*WI* error sets - basic support working


18 files changed, 134 insertions(+), 92 deletions(-)

TODO+11-2
......@@ -1,6 +1,15 @@
1sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find .. -name "*.zig")
1sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find . -name "*.zig")
22
3comptime assert(error{} ! i32 == i32);
3the literal translation of `%T` to this new code is `error!T`.
4however this would not take advantage of error sets. It's
5recommended to generally have all your functions which return possible
6errors to use error set inference, like this:
7
8fn foo() !void {
9
10}
11
12then you can return void, or any error, and the error set is inferred.
413
514// TODO this is an explicit cast and should actually coerce the type
615 erorr set casting
src/analyze.cpp+2-2
......@@ -3367,7 +3367,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *so
33673367}
33683368
33693369ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
3370 ConstCastOnly result = {0};
3370 ConstCastOnly result = {};
33713371 result.id = ConstCastResultIdOk;
33723372
33733373 if (expected_type == actual_type)
......@@ -3465,7 +3465,7 @@ ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_t
34653465 if (result.id == ConstCastResultIdOk) {
34663466 result.id = ConstCastResultIdErrSet;
34673467 }
3468 result.data.error_set.errors.append(contained_error_entry);
3468 result.data.error_set.missing_errors.append(contained_error_entry);
34693469 }
34703470 }
34713471 free(errors);
src/analyze.hpp+3-1
......@@ -214,6 +214,8 @@ struct ConstCastErrSetMismatch {
214214 ZigList<ErrorTableEntry *> missing_errors;
215215};
216216
217struct ConstCastOnly;
218
217219struct ConstCastArg {
218220 size_t arg_index;
219221 ConstCastOnly *child;
......@@ -238,6 +240,6 @@ struct ConstCastOnly {
238240 } data;
239241};
240242
241bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type);
243ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type);
242244
243245#endif
src/ir.cpp+54-29
......@@ -6424,12 +6424,23 @@ enum ImplicitCastMatchResult {
64246424static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type,
64256425 TypeTableEntry *actual_type, IrInstruction *value)
64266426{
6427 if (types_match_const_cast_only(ira->codegen, expected_type, actual_type)) {
6427 ConstCastOnly const_cast_result = types_match_const_cast_only(ira->codegen, expected_type, actual_type);
6428 if (const_cast_result.id == ConstCastResultIdOk) {
64286429 return ImplicitCastMatchResultYes;
64296430 }
64306431
64316432 // if we got here with error sets, make an error showing the incompatibilities
6432 if (expected_typek
6433 if (const_cast_result.id == ConstCastResultIdErrSet) {
6434 ErrorMsg *msg = ir_add_error(ira, value,
6435 buf_sprintf("expected '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name)));
6436 for (size_t i = 0; i < const_cast_result.data.error_set.missing_errors.length; i += 1) {
6437 ErrorTableEntry *error_entry = const_cast_result.data.error_set.missing_errors.at(i);
6438 add_error_note(ira->codegen, msg, error_entry->decl_node,
6439 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name)));
6440 }
6441
6442 return ImplicitCastMatchResultReportedError;
6443 }
64336444
64346445 // implicit conversion from anything to var
64356446 if (expected_type->id == TypeTableEntryIdVar) {
......@@ -6508,7 +6519,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
65086519 assert(ptr_type->id == TypeTableEntryIdPointer);
65096520
65106521 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
6511 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
6522 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type).id == ConstCastResultIdOk)
65126523 {
65136524 return ImplicitCastMatchResultYes;
65146525 }
......@@ -6527,7 +6538,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
65276538 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
65286539
65296540 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
6530 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, array_type->data.array.child_type))
6541 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, array_type->data.array.child_type).id == ConstCastResultIdOk)
65316542 {
65326543 return ImplicitCastMatchResultYes;
65336544 }
......@@ -6543,7 +6554,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
65436554 expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
65446555 assert(ptr_type->id == TypeTableEntryIdPointer);
65456556 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
6546 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
6557 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type).id == ConstCastResultIdOk)
65476558 {
65486559 return ImplicitCastMatchResultYes;
65496560 }
......@@ -6558,7 +6569,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
65586569 expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
65596570 assert(ptr_type->id == TypeTableEntryIdPointer);
65606571 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
6561 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
6572 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type).id == ConstCastResultIdOk)
65626573 {
65636574 return ImplicitCastMatchResultYes;
65646575 }
......@@ -6638,7 +6649,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
66386649 // implicitly take a const pointer to something
66396650 if (!type_requires_comptime(actual_type)) {
66406651 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
6641 if (types_match_const_cast_only(ira->codegen, expected_type, const_ptr_actual)) {
6652 if (types_match_const_cast_only(ira->codegen, expected_type, const_ptr_actual).id == ConstCastResultIdOk) {
66426653 return ImplicitCastMatchResultYes;
66436654 }
66446655 }
......@@ -6742,20 +6753,31 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
67426753 if (cur_is_superset) {
67436754 err_set_type = cur_type;
67446755 prev_inst = cur_inst;
6756 assert(errors != nullptr);
67456757 continue;
67466758 }
67476759
67486760 // neither of them are supersets. so we invent a new error set type that is a union of both of them
67496761 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type);
6762 assert(errors != nullptr);
67506763 continue;
67516764 } else if (cur_type->id == TypeTableEntryIdErrorUnion) {
6765 if (err_set_type == ira->codegen->builtin_types.entry_global_error_set) {
6766 prev_inst = cur_inst;
6767 continue;
6768 }
6769 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;
6770 if (cur_err_set_type == ira->codegen->builtin_types.entry_global_error_set) {
6771 err_set_type = ira->codegen->builtin_types.entry_global_error_set;
6772 prev_inst = cur_inst;
6773 continue;
6774 }
67526775 // test if err_set_type is a subset of cur_type's error set
67536776 // unset everything in errors
67546777 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
67556778 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i];
67566779 errors[error_entry->value] = nullptr;
67576780 }
6758 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;
67596781 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) {
67606782 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i];
67616783 errors[error_entry->value] = error_entry;
......@@ -6772,12 +6794,14 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
67726794 if (cur_is_superset) {
67736795 err_set_type = cur_err_set_type;
67746796 prev_inst = cur_inst;
6797 assert(errors != nullptr);
67756798 continue;
67766799 }
67776800
67786801 // not a subset. invent new error set type, union of both of them
67796802 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type);
67806803 prev_inst = cur_inst;
6804 assert(errors != nullptr);
67816805 continue;
67826806 } else {
67836807 prev_inst = cur_inst;
......@@ -6820,15 +6844,16 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
68206844 }
68216845 // not a subset. invent new error set type, union of both of them
68226846 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type);
6847 assert(errors != nullptr);
68236848 continue;
68246849 }
68256850 }
68266851
6827 if (types_match_const_cast_only(ira->codegen, prev_type, cur_type)) {
6852 if (types_match_const_cast_only(ira->codegen, prev_type, cur_type).id == ConstCastResultIdOk) {
68286853 continue;
68296854 }
68306855
6831 if (types_match_const_cast_only(ira->codegen, cur_type, prev_type)) {
6856 if (types_match_const_cast_only(ira->codegen, cur_type, prev_type).id == ConstCastResultIdOk) {
68326857 prev_inst = cur_inst;
68336858 continue;
68346859 }
......@@ -6851,26 +6876,26 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
68516876 }
68526877
68536878 if (prev_type->id == TypeTableEntryIdErrorUnion &&
6854 types_match_const_cast_only(ira->codegen, prev_type->data.error_union.payload_type, cur_type))
6879 types_match_const_cast_only(ira->codegen, prev_type->data.error_union.payload_type, cur_type).id == ConstCastResultIdOk)
68556880 {
68566881 continue;
68576882 }
68586883
68596884 if (cur_type->id == TypeTableEntryIdErrorUnion &&
6860 types_match_const_cast_only(ira->codegen, cur_type->data.error_union.payload_type, prev_type))
6885 types_match_const_cast_only(ira->codegen, cur_type->data.error_union.payload_type, prev_type).id == ConstCastResultIdOk)
68616886 {
68626887 prev_inst = cur_inst;
68636888 continue;
68646889 }
68656890
68666891 if (prev_type->id == TypeTableEntryIdMaybe &&
6867 types_match_const_cast_only(ira->codegen, prev_type->data.maybe.child_type, cur_type))
6892 types_match_const_cast_only(ira->codegen, prev_type->data.maybe.child_type, cur_type).id == ConstCastResultIdOk)
68686893 {
68696894 continue;
68706895 }
68716896
68726897 if (cur_type->id == TypeTableEntryIdMaybe &&
6873 types_match_const_cast_only(ira->codegen, cur_type->data.maybe.child_type, prev_type))
6898 types_match_const_cast_only(ira->codegen, cur_type->data.maybe.child_type, prev_type).id == ConstCastResultIdOk)
68746899 {
68756900 prev_inst = cur_inst;
68766901 continue;
......@@ -6908,7 +6933,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
69086933
69096934 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
69106935 cur_type->data.array.len != prev_type->data.array.len &&
6911 types_match_const_cast_only(ira->codegen, cur_type->data.array.child_type, prev_type->data.array.child_type))
6936 types_match_const_cast_only(ira->codegen, cur_type->data.array.child_type, prev_type->data.array.child_type).id == ConstCastResultIdOk)
69126937 {
69136938 convert_to_const_slice = true;
69146939 prev_inst = cur_inst;
......@@ -6917,7 +6942,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
69176942
69186943 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
69196944 cur_type->data.array.len != prev_type->data.array.len &&
6920 types_match_const_cast_only(ira->codegen, prev_type->data.array.child_type, cur_type->data.array.child_type))
6945 types_match_const_cast_only(ira->codegen, prev_type->data.array.child_type, cur_type->data.array.child_type).id == ConstCastResultIdOk)
69216946 {
69226947 convert_to_const_slice = true;
69236948 continue;
......@@ -6927,7 +6952,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
69276952 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
69286953 cur_type->data.array.len == 0) &&
69296954 types_match_const_cast_only(ira->codegen, prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
6930 cur_type->data.array.child_type))
6955 cur_type->data.array.child_type).id == ConstCastResultIdOk)
69316956 {
69326957 convert_to_const_slice = false;
69336958 continue;
......@@ -6937,7 +6962,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
69376962 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
69386963 prev_type->data.array.len == 0) &&
69396964 types_match_const_cast_only(ira->codegen, cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
6940 prev_type->data.array.child_type))
6965 prev_type->data.array.child_type).id == ConstCastResultIdOk)
69416966 {
69426967 prev_inst = cur_inst;
69436968 convert_to_const_slice = false;
......@@ -8059,7 +8084,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
80598084 return value;
80608085
80618086 // explicit match or non-const to const
8062 if (types_match_const_cast_only(ira->codegen, wanted_type, actual_type)) {
8087 if (types_match_const_cast_only(ira->codegen, wanted_type, actual_type).id == ConstCastResultIdOk) {
80638088 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
80648089 }
80658090
......@@ -8105,7 +8130,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
81058130 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
81068131 assert(ptr_type->id == TypeTableEntryIdPointer);
81078132 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8108 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
8133 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type).id == ConstCastResultIdOk)
81098134 {
81108135 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
81118136 }
......@@ -8123,7 +8148,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
81238148 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
81248149
81258150 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
8126 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, array_type->data.array.child_type))
8151 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, array_type->data.array.child_type).id == ConstCastResultIdOk)
81278152 {
81288153 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
81298154 }
......@@ -8139,7 +8164,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
81398164 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
81408165 assert(ptr_type->id == TypeTableEntryIdPointer);
81418166 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8142 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
8167 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type).id == ConstCastResultIdOk)
81438168 {
81448169 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
81458170 if (type_is_invalid(cast1->value.type))
......@@ -8162,7 +8187,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
81628187 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
81638188 assert(ptr_type->id == TypeTableEntryIdPointer);
81648189 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8165 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
8190 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type).id == ConstCastResultIdOk)
81668191 {
81678192 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
81688193 if (type_is_invalid(cast1->value.type))
......@@ -8224,7 +8249,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
82248249
82258250 // explicit cast from child type of maybe type to maybe type
82268251 if (wanted_type->id == TypeTableEntryIdMaybe) {
8227 if (types_match_const_cast_only(ira->codegen, wanted_type->data.maybe.child_type, actual_type)) {
8252 if (types_match_const_cast_only(ira->codegen, wanted_type->data.maybe.child_type, actual_type).id == ConstCastResultIdOk) {
82288253 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
82298254 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
82308255 actual_type->id == TypeTableEntryIdNumLitFloat)
......@@ -8246,7 +8271,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
82468271
82478272 // explicit cast from child type of error type to error type
82488273 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
8249 if (types_match_const_cast_only(ira->codegen, wanted_type->data.error_union.payload_type, actual_type)) {
8274 if (types_match_const_cast_only(ira->codegen, wanted_type->data.error_union.payload_type, actual_type).id == ConstCastResultIdOk) {
82508275 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
82518276 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
82528277 actual_type->id == TypeTableEntryIdNumLitFloat)
......@@ -8268,7 +8293,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
82688293 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
82698294 assert(ptr_type->id == TypeTableEntryIdPointer);
82708295 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8271 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
8296 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type).id == ConstCastResultIdOk)
82728297 {
82738298 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
82748299 if (type_is_invalid(cast1->value.type))
......@@ -8295,7 +8320,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
82958320 actual_type->id != TypeTableEntryIdMaybe)
82968321 {
82978322 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
8298 if (types_match_const_cast_only(ira->codegen, wanted_child_type, actual_type) ||
8323 if (types_match_const_cast_only(ira->codegen, wanted_child_type, actual_type).id == ConstCastResultIdOk ||
82998324 actual_type->id == TypeTableEntryIdNullLit ||
83008325 actual_type->id == TypeTableEntryIdNumLitInt ||
83018326 actual_type->id == TypeTableEntryIdNumLitFloat)
......@@ -8445,7 +8470,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
84458470 // explicit cast from something to const pointer of it
84468471 if (!type_requires_comptime(actual_type)) {
84478472 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
8448 if (types_match_const_cast_only(ira->codegen, wanted_type, const_ptr_actual)) {
8473 if (types_match_const_cast_only(ira->codegen, wanted_type, const_ptr_actual).id == ConstCastResultIdOk) {
84498474 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);
84508475 }
84518476 }
......@@ -8473,7 +8498,7 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
84738498 ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->value.type, value);
84748499 switch (result) {
84758500 case ImplicitCastMatchResultNo:
8476 ErrorMsg *msg = ir_add_error(ira, value,
8501 ir_add_error(ira, value,
84778502 buf_sprintf("expected type '%s', found '%s'",
84788503 buf_ptr(&expected_type->name),
84798504 buf_ptr(&value->value.type->name)));
std/debug/index.zig+1-2
......@@ -209,8 +209,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a
209209 try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");
210210 }
211211 } else |err| switch (err) {
212 error.EndOfFile, error.PathNotFound => {},
213 else => return err,
212 error.EndOfFile => {},
214213 }
215214 } else |err| switch (err) {
216215 error.MissingDebugInfo, error.InvalidDebugInfo => {
std/fmt/index.zig+20-13
......@@ -195,7 +195,7 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@
195195 const T = @typeOf(value);
196196 switch (@typeId(T)) {
197197 builtin.TypeId.Int => {
198 return formatInt(value, 10, false, 0, context, output);
198 return formatInt(value, 10, false, 0, context, Errors, output);
199199 },
200200 builtin.TypeId.Float => {
201201 return formatFloat(value, context, output);
......@@ -290,7 +290,7 @@ pub fn formatFloat(value: var, context: var, comptime Errors: type, output: fn(@
290290
291291 if (float_decimal.exp != 1) {
292292 try output(context, "e");
293 try formatInt(float_decimal.exp - 1, 10, false, 0, context, output);
293 try formatInt(float_decimal.exp - 1, 10, false, 0, context, Errors, output);
294294 }
295295}
296296
......@@ -336,12 +336,12 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, comptime E
336336
337337
338338pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
339 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)errors!void) errors!void
339 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
340340{
341341 if (@typeOf(value).is_signed) {
342 return formatIntSigned(value, base, uppercase, width, context, output);
342 return formatIntSigned(value, base, uppercase, width, context, Errors, output);
343343 } else {
344 return formatIntUnsigned(value, base, uppercase, width, context, output);
344 return formatIntUnsigned(value, base, uppercase, width, context, Errors, output);
345345 }
346346}
347347
......@@ -354,15 +354,15 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
354354 try output(context, (&minus_sign)[0..1]);
355355 const new_value = uint(-(value + 1)) + 1;
356356 const new_width = if (width == 0) 0 else (width - 1);
357 return formatIntUnsigned(new_value, base, uppercase, new_width, context, output);
357 return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output);
358358 } else if (width == 0) {
359 return formatIntUnsigned(uint(value), base, uppercase, width, context, output);
359 return formatIntUnsigned(uint(value), base, uppercase, width, context, Errors, output);
360360 } else {
361361 const plus_sign: u8 = '+';
362362 try output(context, (&plus_sign)[0..1]);
363363 const new_value = uint(value);
364364 const new_width = if (width == 0) 0 else (width - 1);
365 return formatIntUnsigned(new_value, base, uppercase, new_width, context, output);
365 return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output);
366366 }
367367}
368368
......@@ -410,7 +410,7 @@ pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width:
410410 .out_buf = out_buf,
411411 .index = 0,
412412 };
413 formatInt(value, base, uppercase, width, &context, formatIntCallback) catch unreachable;
413 formatInt(value, base, uppercase, width, &context, error{}, formatIntCallback) catch unreachable;
414414 return context.index;
415415}
416416const FormatIntBuf = struct {
......@@ -446,7 +446,14 @@ test "fmt.parseInt" {
446446 assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
447447}
448448
449pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) !T {
449const ParseUnsignedError = error {
450 /// The result cannot fit in the type specified
451 Overflow,
452 /// The input had a byte that was not a digit
453 InvalidCharacter,
454};
455
456pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsignedError!T {
450457 var x: T = 0;
451458
452459 for (buf) |c| {
......@@ -458,16 +465,16 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) !T {
458465 return x;
459466}
460467
461fn charToDigit(c: u8, radix: u8) !u8 {
468fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
462469 const value = switch (c) {
463470 '0' ... '9' => c - '0',
464471 'A' ... 'Z' => c - 'A' + 10,
465472 'a' ... 'z' => c - 'a' + 10,
466 else => return error.InvalidChar,
473 else => return error.InvalidCharacter,
467474 };
468475
469476 if (value >= radix)
470 return error.InvalidChar;
477 return error.InvalidCharacter;
471478
472479 return value;
473480}
std/math/index.zig+3-3
......@@ -191,17 +191,17 @@ test "math.max" {
191191 assert(max(i32(-1), i32(2)) == 2);
192192}
193193
194pub fn mul(comptime T: type, a: T, b: T) !T {
194pub fn mul(comptime T: type, a: T, b: T) (error{Overflow}!T) {
195195 var answer: T = undefined;
196196 return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
197197}
198198
199pub fn add(comptime T: type, a: T, b: T) !T {
199pub fn add(comptime T: type, a: T, b: T) (error{Overflow}!T) {
200200 var answer: T = undefined;
201201 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
202202}
203203
204pub fn sub(comptime T: type, a: T, b: T) !T {
204pub fn sub(comptime T: type, a: T, b: T) (error{Overflow}!T) {
205205 var answer: T = undefined;
206206 return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
207207}
test/cases/cast.zig+16-16
......@@ -74,7 +74,7 @@ test "string literal to &const []const u8" {
7474 assert(mem.eql(u8, *x, "hello"));
7575}
7676
77test "implicitly cast from T to %?T" {
77test "implicitly cast from T to error!?T" {
7878 castToMaybeTypeError(1);
7979 comptime castToMaybeTypeError(1);
8080}
......@@ -83,37 +83,37 @@ const A = struct {
8383};
8484fn castToMaybeTypeError(z: i32) void {
8585 const x = i32(1);
86 const y: %?i32 = x;
86 const y: error!?i32 = x;
8787 assert(??(try y) == 1);
8888
8989 const f = z;
90 const g: %?i32 = f;
90 const g: error!?i32 = f;
9191
9292 const a = A{ .a = z };
93 const b: %?A = a;
93 const b: error!?A = a;
9494 assert((??(b catch unreachable)).a == 1);
9595}
9696
97test "implicitly cast from int to %?T" {
97test "implicitly cast from int to error!?T" {
9898 implicitIntLitToMaybe();
9999 comptime implicitIntLitToMaybe();
100100}
101101fn implicitIntLitToMaybe() void {
102102 const f: ?i32 = 1;
103 const g: %?i32 = 1;
103 const g: error!?i32 = 1;
104104}
105105
106106
107test "return null from fn() %?&T" {
107test "return null from fn() error!?&T" {
108108 const a = returnNullFromMaybeTypeErrorRef();
109109 const b = returnNullLitFromMaybeTypeErrorRef();
110110 assert((try a) == null and (try b) == null);
111111}
112fn returnNullFromMaybeTypeErrorRef() !?&A {
112fn returnNullFromMaybeTypeErrorRef() error!?&A {
113113 const a: ?&A = null;
114114 return a;
115115}
116fn returnNullLitFromMaybeTypeErrorRef() !?&A {
116fn returnNullLitFromMaybeTypeErrorRef() error!?&A {
117117 return null;
118118}
119119
......@@ -160,7 +160,7 @@ fn castToMaybeSlice() ?[]const u8 {
160160}
161161
162162
163test "implicitly cast from [0]T to %[]T" {
163test "implicitly cast from [0]T to error![]T" {
164164 testCastZeroArrayToErrSliceMut();
165165 comptime testCastZeroArrayToErrSliceMut();
166166}
......@@ -169,11 +169,11 @@ fn testCastZeroArrayToErrSliceMut() void {
169169 assert((gimmeErrOrSlice() catch unreachable).len == 0);
170170}
171171
172fn gimmeErrOrSlice() ![]u8 {
172fn gimmeErrOrSlice() error![]u8 {
173173 return []u8{};
174174}
175175
176test "peer type resolution: [0]u8, []const u8, and %[]u8" {
176test "peer type resolution: [0]u8, []const u8, and error![]u8" {
177177 {
178178 var data = "hi";
179179 const slice = data[0..];
......@@ -187,7 +187,7 @@ test "peer type resolution: [0]u8, []const u8, and %[]u8" {
187187 assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
188188 }
189189}
190fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) ![]u8 {
190fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) error![]u8 {
191191 if (a) {
192192 return []u8{};
193193 }
......@@ -229,7 +229,7 @@ fn foo(args: ...) void {
229229
230230
231231test "peer type resolution: error and [N]T" {
232 // TODO: implicit %T to %U where T can implicitly cast to U
232 // TODO: implicit error!T to error!U where T can implicitly cast to U
233233 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
234234 //comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
235235
......@@ -237,13 +237,13 @@ test "peer type resolution: error and [N]T" {
237237 comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
238238}
239239
240//fn testPeerErrorAndArray(x: u8) ![]const u8 {
240//fn testPeerErrorAndArray(x: u8) error![]const u8 {
241241// return switch (x) {
242242// 0x00 => "OK",
243243// else => error.BadValue,
244244// };
245245//}
246fn testPeerErrorAndArray2(x: u8) ![]const u8 {
246fn testPeerErrorAndArray2(x: u8) error![]const u8 {
247247 return switch (x) {
248248 0x00 => "OK",
249249 0x01 => "OKK",
test/cases/enum_with_members.zig+1-1
......@@ -6,7 +6,7 @@ const ET = union(enum) {
66 SINT: i32,
77 UINT: u32,
88
9 pub fn print(a: &const ET, buf: []u8) !usize {
9 pub fn print(a: &const ET, buf: []u8) error!usize {
1010 return switch (*a) {
1111 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
1212 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
test/cases/error.zig+7-7
......@@ -1,16 +1,16 @@
11const assert = @import("std").debug.assert;
22const mem = @import("std").mem;
33
4pub fn foo() !i32 {
4pub fn foo() error!i32 {
55 const x = try bar();
66 return x + 1;
77}
88
9pub fn bar() !i32 {
9pub fn bar() error!i32 {
1010 return 13;
1111}
1212
13pub fn baz() !i32 {
13pub fn baz() error!i32 {
1414 const y = foo() catch 1234;
1515 return y + 1;
1616}
......@@ -50,7 +50,7 @@ test "error binary operator" {
5050 assert(a == 3);
5151 assert(b == 10);
5252}
53fn errBinaryOperatorG(x: bool) !isize {
53fn errBinaryOperatorG(x: bool) error!isize {
5454 return if (x) error.ItBroke else isize(10);
5555}
5656
......@@ -59,18 +59,18 @@ test "unwrap simple value from error" {
5959 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
6060 assert(i == 13);
6161}
62fn unwrapSimpleValueFromErrorDo() %isize { return 13; }
62fn unwrapSimpleValueFromErrorDo() error!isize { return 13; }
6363
6464
6565test "error return in assignment" {
6666 doErrReturnInAssignment() catch unreachable;
6767}
6868
69fn doErrReturnInAssignment() !void {
69fn doErrReturnInAssignment() error!void {
7070 var x : i32 = undefined;
7171 x = try makeANonErr();
7272}
7373
74fn makeANonErr() !i32 {
74fn makeANonErr() error!i32 {
7575 return 1;
7676}
test/cases/ir_block_deps.zig+1-1
......@@ -11,7 +11,7 @@ fn foo(id: u64) !i32 {
1111 };
1212}
1313
14fn getErrInt() %i32 { return 0; }
14fn getErrInt() error!i32 { return 0; }
1515
1616test "ir block deps" {
1717 assert((foo(1) catch unreachable) == 0);
test/cases/misc.zig+4-4
......@@ -262,7 +262,7 @@ test "generic malloc free" {
262262 memFree(u8, a);
263263}
264264const some_mem : [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) ![]T {
265fn memAlloc(comptime T: type, n: usize) error![]T {
266266 return @ptrCast(&T, &some_mem[0])[0..n];
267267}
268268fn memFree(comptime T: type, memory: []T) void { }
......@@ -419,7 +419,7 @@ test "cast slice to u8 slice" {
419419test "pointer to void return type" {
420420 testPointerToVoidReturnType() catch unreachable;
421421}
422fn testPointerToVoidReturnType() !void {
422fn testPointerToVoidReturnType() error!void {
423423 const a = testPointerToVoidReturnType2();
424424 return *a;
425425}
......@@ -475,8 +475,8 @@ test "@typeId" {
475475 assert(@typeId(@typeOf(undefined)) == Tid.UndefinedLiteral);
476476 assert(@typeId(@typeOf(null)) == Tid.NullLiteral);
477477 assert(@typeId(?i32) == Tid.Nullable);
478 assert(@typeId(%i32) == Tid.ErrorUnion);
479 assert(@typeId(error) == Tid.Error);
478 assert(@typeId(error!i32) == Tid.ErrorUnion);
479 assert(@typeId(error) == Tid.ErrorSet);
480480 assert(@typeId(AnEnum) == Tid.Enum);
481481 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
482482 assert(@typeId(AUnionEnum) == Tid.Union);
test/cases/reflection.zig+1-1
......@@ -5,7 +5,7 @@ test "reflection: array, pointer, nullable, error union type child" {
55 comptime {
66 assert(([10]u8).Child == u8);
77 assert((&u8).Child == u8);
8 assert((%u8).Child == u8);
8 assert((error!u8).Payload == u8);
99 assert((?u8).Child == u8);
1010 }
1111}
test/cases/switch.zig+1-1
......@@ -225,7 +225,7 @@ fn switchWithUnreachable(x: i32) i32 {
225225 return 10;
226226}
227227
228fn return_a_number() !i32 {
228fn return_a_number() error!i32 {
229229 return 1;
230230}
231231
test/cases/switch_prong_err_enum.zig+2-2
......@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
22
33var read_count: u64 = 0;
44
5fn readOnce() !u64 {
5fn readOnce() error!u64 {
66 read_count += 1;
77 return read_count;
88}
......@@ -12,7 +12,7 @@ const FormValue = union(enum) {
1212 Other: bool,
1313};
1414
15fn doThing(form_id: u64) !FormValue {
15fn doThing(form_id: u64) error!FormValue {
1616 return switch (form_id) {
1717 17 => FormValue { .Address = try readOnce() },
1818 else => error.InvalidDebugInfo,
test/cases/try.zig+2-2
......@@ -17,7 +17,7 @@ fn tryOnErrorUnionImpl() void {
1717 assert(x == 11);
1818}
1919
20fn returnsTen() !i32 {
20fn returnsTen() error!i32 {
2121 return 10;
2222}
2323
......@@ -29,7 +29,7 @@ test "try without vars" {
2929 assert(result2 == 1);
3030}
3131
32fn failIfTrue(ok: bool) !void {
32fn failIfTrue(ok: bool) error!void {
3333 if (ok) {
3434 return error.ItBroke;
3535 } else {
test/cases/union.zig+1-1
......@@ -13,7 +13,7 @@ const Agg = struct {
1313const v1 = Value { .Int = 1234 };
1414const v2 = Value { .Array = []u8{3} ** 9 };
1515
16const err = (%Agg)(Agg {
16const err = (error!Agg)(Agg {
1717 .val1 = v1,
1818 .val2 = v2,
1919});
test/cases/while.zig+4-4
......@@ -50,7 +50,7 @@ fn runContinueAndBreakTest() void {
5050test "return with implicit cast from while loop" {
5151 returnWithImplicitCastFromWhileLoopTest() catch unreachable;
5252}
53fn returnWithImplicitCastFromWhileLoopTest() !void {
53fn returnWithImplicitCastFromWhileLoopTest() error!void {
5454 while (true) {
5555 return;
5656 }
......@@ -116,7 +116,7 @@ test "while with error union condition" {
116116}
117117
118118var numbers_left: i32 = undefined;
119fn getNumberOrErr() !i32 {
119fn getNumberOrErr() error!i32 {
120120 return if (numbers_left == 0)
121121 error.OutOfNumbers
122122 else x: {
......@@ -204,7 +204,7 @@ fn testContinueOuter() void {
204204
205205fn returnNull() ?i32 { return null; }
206206fn returnMaybe(x: i32) ?i32 { return x; }
207fn returnError() %i32 { return error.YouWantedAnError; }
208fn returnSuccess(x: i32) %i32 { return x; }
207fn returnError() error!i32 { return error.YouWantedAnError; }
208fn returnSuccess(x: i32) error!i32 { return x; }
209209fn returnFalse() bool { return false; }
210210fn returnTrue() bool { return true; }