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 @@...@@ -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
5// TODO this is an explicit cast and should actually coerce the type14// TODO this is an explicit cast and should actually coerce the type
6 erorr set casting15 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...@@ -3367,7 +3367,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *so
3367}3367}
33683368
3369ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type) {3369ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
3370 ConstCastOnly result = {0};3370 ConstCastOnly result = {};
3371 result.id = ConstCastResultIdOk;3371 result.id = ConstCastResultIdOk;
33723372
3373 if (expected_type == actual_type)3373 if (expected_type == actual_type)
...@@ -3465,7 +3465,7 @@ ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_t...@@ -3465,7 +3465,7 @@ ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_t
3465 if (result.id == ConstCastResultIdOk) {3465 if (result.id == ConstCastResultIdOk) {
3466 result.id = ConstCastResultIdErrSet;3466 result.id = ConstCastResultIdErrSet;
3467 }3467 }
3468 result.data.error_set.errors.append(contained_error_entry);3468 result.data.error_set.missing_errors.append(contained_error_entry);
3469 }3469 }
3470 }3470 }
3471 free(errors);3471 free(errors);
src/analyze.hpp+3-1
...@@ -214,6 +214,8 @@ struct ConstCastErrSetMismatch {...@@ -214,6 +214,8 @@ struct ConstCastErrSetMismatch {
214 ZigList<ErrorTableEntry *> missing_errors;214 ZigList<ErrorTableEntry *> missing_errors;
215};215};
216216
217struct ConstCastOnly;
218
217struct ConstCastArg {219struct ConstCastArg {
218 size_t arg_index;220 size_t arg_index;
219 ConstCastOnly *child;221 ConstCastOnly *child;
...@@ -238,6 +240,6 @@ struct ConstCastOnly {...@@ -238,6 +240,6 @@ struct ConstCastOnly {
238 } data;240 } data;
239};241};
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
243#endif245#endif
src/ir.cpp+54-29
...@@ -6424,12 +6424,23 @@ enum ImplicitCastMatchResult {...@@ -6424,12 +6424,23 @@ enum ImplicitCastMatchResult {
6424static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type,6424static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type,
6425 TypeTableEntry *actual_type, IrInstruction *value)6425 TypeTableEntry *actual_type, IrInstruction *value)
6426{6426{
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) {
6428 return ImplicitCastMatchResultYes;6429 return ImplicitCastMatchResultYes;
6429 }6430 }
64306431
6431 // if we got here with error sets, make an error showing the incompatibilities6432 // if we got here with error sets, make an error showing the incompatibilities
6432 if (expected_typek6433 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
6434 // implicit conversion from anything to var6445 // implicit conversion from anything to var
6435 if (expected_type->id == TypeTableEntryIdVar) {6446 if (expected_type->id == TypeTableEntryIdVar) {
...@@ -6508,7 +6519,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6508,7 +6519,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6508 assert(ptr_type->id == TypeTableEntryIdPointer);6519 assert(ptr_type->id == TypeTableEntryIdPointer);
65096520
6510 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&6521 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)
6512 {6523 {
6513 return ImplicitCastMatchResultYes;6524 return ImplicitCastMatchResultYes;
6514 }6525 }
...@@ -6527,7 +6538,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6527,7 +6538,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6527 TypeTableEntry *array_type = actual_type->data.pointer.child_type;6538 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
65286539
6529 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&6540 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)
6531 {6542 {
6532 return ImplicitCastMatchResultYes;6543 return ImplicitCastMatchResultYes;
6533 }6544 }
...@@ -6543,7 +6554,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6543,7 +6554,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6543 expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;6554 expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
6544 assert(ptr_type->id == TypeTableEntryIdPointer);6555 assert(ptr_type->id == TypeTableEntryIdPointer);
6545 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&6556 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)
6547 {6558 {
6548 return ImplicitCastMatchResultYes;6559 return ImplicitCastMatchResultYes;
6549 }6560 }
...@@ -6558,7 +6569,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6558,7 +6569,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6558 expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;6569 expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
6559 assert(ptr_type->id == TypeTableEntryIdPointer);6570 assert(ptr_type->id == TypeTableEntryIdPointer);
6560 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&6571 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)
6562 {6573 {
6563 return ImplicitCastMatchResultYes;6574 return ImplicitCastMatchResultYes;
6564 }6575 }
...@@ -6638,7 +6649,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6638,7 +6649,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6638 // implicitly take a const pointer to something6649 // implicitly take a const pointer to something
6639 if (!type_requires_comptime(actual_type)) {6650 if (!type_requires_comptime(actual_type)) {
6640 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);6651 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) {
6642 return ImplicitCastMatchResultYes;6653 return ImplicitCastMatchResultYes;
6643 }6654 }
6644 }6655 }
...@@ -6742,20 +6753,31 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6742,20 +6753,31 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6742 if (cur_is_superset) {6753 if (cur_is_superset) {
6743 err_set_type = cur_type;6754 err_set_type = cur_type;
6744 prev_inst = cur_inst;6755 prev_inst = cur_inst;
6756 assert(errors != nullptr);
6745 continue;6757 continue;
6746 }6758 }
67476759
6748 // neither of them are supersets. so we invent a new error set type that is a union of both of them6760 // neither of them are supersets. so we invent a new error set type that is a union of both of them
6749 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type);6761 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type);
6762 assert(errors != nullptr);
6750 continue;6763 continue;
6751 } else if (cur_type->id == TypeTableEntryIdErrorUnion) {6764 } 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 }
6752 // test if err_set_type is a subset of cur_type's error set6775 // test if err_set_type is a subset of cur_type's error set
6753 // unset everything in errors6776 // unset everything in errors
6754 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {6777 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) {
6755 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i];6778 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i];
6756 errors[error_entry->value] = nullptr;6779 errors[error_entry->value] = nullptr;
6757 }6780 }
6758 TypeTableEntry *cur_err_set_type = cur_type->data.error_union.err_set_type;
6759 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) {6781 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) {
6760 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i];6782 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i];
6761 errors[error_entry->value] = error_entry;6783 errors[error_entry->value] = error_entry;
...@@ -6772,12 +6794,14 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6772,12 +6794,14 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6772 if (cur_is_superset) {6794 if (cur_is_superset) {
6773 err_set_type = cur_err_set_type;6795 err_set_type = cur_err_set_type;
6774 prev_inst = cur_inst;6796 prev_inst = cur_inst;
6797 assert(errors != nullptr);
6775 continue;6798 continue;
6776 }6799 }
67776800
6778 // not a subset. invent new error set type, union of both of them6801 // not a subset. invent new error set type, union of both of them
6779 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type);6802 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type);
6780 prev_inst = cur_inst;6803 prev_inst = cur_inst;
6804 assert(errors != nullptr);
6781 continue;6805 continue;
6782 } else {6806 } else {
6783 prev_inst = cur_inst;6807 prev_inst = cur_inst;
...@@ -6820,15 +6844,16 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6820,15 +6844,16 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6820 }6844 }
6821 // not a subset. invent new error set type, union of both of them6845 // not a subset. invent new error set type, union of both of them
6822 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type);6846 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type);
6847 assert(errors != nullptr);
6823 continue;6848 continue;
6824 }6849 }
6825 }6850 }
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) {
6828 continue;6853 continue;
6829 }6854 }
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) {
6832 prev_inst = cur_inst;6857 prev_inst = cur_inst;
6833 continue;6858 continue;
6834 }6859 }
...@@ -6851,26 +6876,26 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6851,26 +6876,26 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6851 }6876 }
68526877
6853 if (prev_type->id == TypeTableEntryIdErrorUnion &&6878 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)
6855 {6880 {
6856 continue;6881 continue;
6857 }6882 }
68586883
6859 if (cur_type->id == TypeTableEntryIdErrorUnion &&6884 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)
6861 {6886 {
6862 prev_inst = cur_inst;6887 prev_inst = cur_inst;
6863 continue;6888 continue;
6864 }6889 }
68656890
6866 if (prev_type->id == TypeTableEntryIdMaybe &&6891 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)
6868 {6893 {
6869 continue;6894 continue;
6870 }6895 }
68716896
6872 if (cur_type->id == TypeTableEntryIdMaybe &&6897 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)
6874 {6899 {
6875 prev_inst = cur_inst;6900 prev_inst = cur_inst;
6876 continue;6901 continue;
...@@ -6908,7 +6933,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6908,7 +6933,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
69086933
6909 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&6934 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
6910 cur_type->data.array.len != prev_type->data.array.len &&6935 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)
6912 {6937 {
6913 convert_to_const_slice = true;6938 convert_to_const_slice = true;
6914 prev_inst = cur_inst;6939 prev_inst = cur_inst;
...@@ -6917,7 +6942,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6917,7 +6942,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
69176942
6918 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&6943 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
6919 cur_type->data.array.len != prev_type->data.array.len &&6944 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)
6921 {6946 {
6922 convert_to_const_slice = true;6947 convert_to_const_slice = true;
6923 continue;6948 continue;
...@@ -6927,7 +6952,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6927,7 +6952,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6927 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||6952 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
6928 cur_type->data.array.len == 0) &&6953 cur_type->data.array.len == 0) &&
6929 types_match_const_cast_only(ira->codegen, prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,6954 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)
6931 {6956 {
6932 convert_to_const_slice = false;6957 convert_to_const_slice = false;
6933 continue;6958 continue;
...@@ -6937,7 +6962,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6937,7 +6962,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6937 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||6962 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
6938 prev_type->data.array.len == 0) &&6963 prev_type->data.array.len == 0) &&
6939 types_match_const_cast_only(ira->codegen, cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,6964 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)
6941 {6966 {
6942 prev_inst = cur_inst;6967 prev_inst = cur_inst;
6943 convert_to_const_slice = false;6968 convert_to_const_slice = false;
...@@ -8059,7 +8084,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8059,7 +8084,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8059 return value;8084 return value;
80608085
8061 // explicit match or non-const to const8086 // 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) {
8063 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);8088 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
8064 }8089 }
80658090
...@@ -8105,7 +8130,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8105,7 +8130,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8105 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;8130 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
8106 assert(ptr_type->id == TypeTableEntryIdPointer);8131 assert(ptr_type->id == TypeTableEntryIdPointer);
8107 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8132 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)
8109 {8134 {
8110 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);8135 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
8111 }8136 }
...@@ -8123,7 +8148,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8123,7 +8148,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8123 TypeTableEntry *array_type = actual_type->data.pointer.child_type;8148 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
81248149
8125 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&8150 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)
8127 {8152 {
8128 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);8153 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
8129 }8154 }
...@@ -8139,7 +8164,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8139,7 +8164,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8139 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;8164 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
8140 assert(ptr_type->id == TypeTableEntryIdPointer);8165 assert(ptr_type->id == TypeTableEntryIdPointer);
8141 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8166 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)
8143 {8168 {
8144 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);8169 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
8145 if (type_is_invalid(cast1->value.type))8170 if (type_is_invalid(cast1->value.type))
...@@ -8162,7 +8187,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8162,7 +8187,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8162 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;8187 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
8163 assert(ptr_type->id == TypeTableEntryIdPointer);8188 assert(ptr_type->id == TypeTableEntryIdPointer);
8164 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8189 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)
8166 {8191 {
8167 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);8192 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
8168 if (type_is_invalid(cast1->value.type))8193 if (type_is_invalid(cast1->value.type))
...@@ -8224,7 +8249,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8224,7 +8249,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
82248249
8225 // explicit cast from child type of maybe type to maybe type8250 // explicit cast from child type of maybe type to maybe type
8226 if (wanted_type->id == TypeTableEntryIdMaybe) {8251 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) {
8228 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);8253 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
8229 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||8254 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
8230 actual_type->id == TypeTableEntryIdNumLitFloat)8255 actual_type->id == TypeTableEntryIdNumLitFloat)
...@@ -8246,7 +8271,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8246,7 +8271,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
82468271
8247 // explicit cast from child type of error type to error type8272 // explicit cast from child type of error type to error type
8248 if (wanted_type->id == TypeTableEntryIdErrorUnion) {8273 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) {
8250 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);8275 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
8251 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||8276 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
8252 actual_type->id == TypeTableEntryIdNumLitFloat)8277 actual_type->id == TypeTableEntryIdNumLitFloat)
...@@ -8268,7 +8293,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8268,7 +8293,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8268 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;8293 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
8269 assert(ptr_type->id == TypeTableEntryIdPointer);8294 assert(ptr_type->id == TypeTableEntryIdPointer);
8270 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8295 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)
8272 {8297 {
8273 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);8298 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
8274 if (type_is_invalid(cast1->value.type))8299 if (type_is_invalid(cast1->value.type))
...@@ -8295,7 +8320,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8295,7 +8320,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8295 actual_type->id != TypeTableEntryIdMaybe)8320 actual_type->id != TypeTableEntryIdMaybe)
8296 {8321 {
8297 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;8322 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 ||
8299 actual_type->id == TypeTableEntryIdNullLit ||8324 actual_type->id == TypeTableEntryIdNullLit ||
8300 actual_type->id == TypeTableEntryIdNumLitInt ||8325 actual_type->id == TypeTableEntryIdNumLitInt ||
8301 actual_type->id == TypeTableEntryIdNumLitFloat)8326 actual_type->id == TypeTableEntryIdNumLitFloat)
...@@ -8445,7 +8470,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8445,7 +8470,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8445 // explicit cast from something to const pointer of it8470 // explicit cast from something to const pointer of it
8446 if (!type_requires_comptime(actual_type)) {8471 if (!type_requires_comptime(actual_type)) {
8447 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);8472 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) {
8449 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);8474 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);
8450 }8475 }
8451 }8476 }
...@@ -8473,7 +8498,7 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ...@@ -8473,7 +8498,7 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
8473 ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->value.type, value);8498 ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->value.type, value);
8474 switch (result) {8499 switch (result) {
8475 case ImplicitCastMatchResultNo:8500 case ImplicitCastMatchResultNo:
8476 ErrorMsg *msg = ir_add_error(ira, value,8501 ir_add_error(ira, value,
8477 buf_sprintf("expected type '%s', found '%s'",8502 buf_sprintf("expected type '%s', found '%s'",
8478 buf_ptr(&expected_type->name),8503 buf_ptr(&expected_type->name),
8479 buf_ptr(&value->value.type->name)));8504 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...@@ -209,8 +209,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a
209 try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");209 try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");
210 }210 }
211 } else |err| switch (err) {211 } else |err| switch (err) {
212 error.EndOfFile, error.PathNotFound => {},212 error.EndOfFile => {},
213 else => return err,
214 }213 }
215 } else |err| switch (err) {214 } else |err| switch (err) {
216 error.MissingDebugInfo, error.InvalidDebugInfo => {215 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(@...@@ -195,7 +195,7 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@
195 const T = @typeOf(value);195 const T = @typeOf(value);
196 switch (@typeId(T)) {196 switch (@typeId(T)) {
197 builtin.TypeId.Int => {197 builtin.TypeId.Int => {
198 return formatInt(value, 10, false, 0, context, output);198 return formatInt(value, 10, false, 0, context, Errors, output);
199 },199 },
200 builtin.TypeId.Float => {200 builtin.TypeId.Float => {
201 return formatFloat(value, context, output);201 return formatFloat(value, context, output);
...@@ -290,7 +290,7 @@ pub fn formatFloat(value: var, context: var, comptime Errors: type, output: fn(@...@@ -290,7 +290,7 @@ pub fn formatFloat(value: var, context: var, comptime Errors: type, output: fn(@
290290
291 if (float_decimal.exp != 1) {291 if (float_decimal.exp != 1) {
292 try output(context, "e");292 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);
294 }294 }
295}295}
296296
...@@ -336,12 +336,12 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, comptime E...@@ -336,12 +336,12 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, comptime E
336336
337337
338pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,338pub 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!void339 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
340{340{
341 if (@typeOf(value).is_signed) {341 if (@typeOf(value).is_signed) {
342 return formatIntSigned(value, base, uppercase, width, context, output);342 return formatIntSigned(value, base, uppercase, width, context, Errors, output);
343 } else {343 } else {
344 return formatIntUnsigned(value, base, uppercase, width, context, output);344 return formatIntUnsigned(value, base, uppercase, width, context, Errors, output);
345 }345 }
346}346}
347347
...@@ -354,15 +354,15 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,...@@ -354,15 +354,15 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
354 try output(context, (&minus_sign)[0..1]);354 try output(context, (&minus_sign)[0..1]);
355 const new_value = uint(-(value + 1)) + 1;355 const new_value = uint(-(value + 1)) + 1;
356 const new_width = if (width == 0) 0 else (width - 1);356 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);
358 } else if (width == 0) {358 } 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);
360 } else {360 } else {
361 const plus_sign: u8 = '+';361 const plus_sign: u8 = '+';
362 try output(context, (&plus_sign)[0..1]);362 try output(context, (&plus_sign)[0..1]);
363 const new_value = uint(value);363 const new_value = uint(value);
364 const new_width = if (width == 0) 0 else (width - 1);364 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);
366 }366 }
367}367}
368368
...@@ -410,7 +410,7 @@ pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width:...@@ -410,7 +410,7 @@ pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width:
410 .out_buf = out_buf,410 .out_buf = out_buf,
411 .index = 0,411 .index = 0,
412 };412 };
413 formatInt(value, base, uppercase, width, &context, formatIntCallback) catch unreachable;413 formatInt(value, base, uppercase, width, &context, error{}, formatIntCallback) catch unreachable;
414 return context.index;414 return context.index;
415}415}
416const FormatIntBuf = struct {416const FormatIntBuf = struct {
...@@ -446,7 +446,14 @@ test "fmt.parseInt" {...@@ -446,7 +446,14 @@ test "fmt.parseInt" {
446 assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);446 assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
447}447}
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 {
450 var x: T = 0;457 var x: T = 0;
451458
452 for (buf) |c| {459 for (buf) |c| {
...@@ -458,16 +465,16 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) !T {...@@ -458,16 +465,16 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) !T {
458 return x;465 return x;
459}466}
460467
461fn charToDigit(c: u8, radix: u8) !u8 {468fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
462 const value = switch (c) {469 const value = switch (c) {
463 '0' ... '9' => c - '0',470 '0' ... '9' => c - '0',
464 'A' ... 'Z' => c - 'A' + 10,471 'A' ... 'Z' => c - 'A' + 10,
465 'a' ... 'z' => c - 'a' + 10,472 'a' ... 'z' => c - 'a' + 10,
466 else => return error.InvalidChar,473 else => return error.InvalidCharacter,
467 };474 };
468475
469 if (value >= radix)476 if (value >= radix)
470 return error.InvalidChar;477 return error.InvalidCharacter;
471478
472 return value;479 return value;
473}480}
std/math/index.zig+3-3
...@@ -191,17 +191,17 @@ test "math.max" {...@@ -191,17 +191,17 @@ test "math.max" {
191 assert(max(i32(-1), i32(2)) == 2);191 assert(max(i32(-1), i32(2)) == 2);
192}192}
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) {
195 var answer: T = undefined;195 var answer: T = undefined;
196 return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;196 return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
197}197}
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) {
200 var answer: T = undefined;200 var answer: T = undefined;
201 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;201 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
202}202}
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) {
205 var answer: T = undefined;205 var answer: T = undefined;
206 return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;206 return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
207}207}
test/cases/cast.zig+16-16
...@@ -74,7 +74,7 @@ test "string literal to &const []const u8" {...@@ -74,7 +74,7 @@ test "string literal to &const []const u8" {
74 assert(mem.eql(u8, *x, "hello"));74 assert(mem.eql(u8, *x, "hello"));
75}75}
7676
77test "implicitly cast from T to %?T" {77test "implicitly cast from T to error!?T" {
78 castToMaybeTypeError(1);78 castToMaybeTypeError(1);
79 comptime castToMaybeTypeError(1);79 comptime castToMaybeTypeError(1);
80}80}
...@@ -83,37 +83,37 @@ const A = struct {...@@ -83,37 +83,37 @@ const A = struct {
83};83};
84fn castToMaybeTypeError(z: i32) void {84fn castToMaybeTypeError(z: i32) void {
85 const x = i32(1);85 const x = i32(1);
86 const y: %?i32 = x;86 const y: error!?i32 = x;
87 assert(??(try y) == 1);87 assert(??(try y) == 1);
8888
89 const f = z;89 const f = z;
90 const g: %?i32 = f;90 const g: error!?i32 = f;
9191
92 const a = A{ .a = z };92 const a = A{ .a = z };
93 const b: %?A = a;93 const b: error!?A = a;
94 assert((??(b catch unreachable)).a == 1);94 assert((??(b catch unreachable)).a == 1);
95}95}
9696
97test "implicitly cast from int to %?T" {97test "implicitly cast from int to error!?T" {
98 implicitIntLitToMaybe();98 implicitIntLitToMaybe();
99 comptime implicitIntLitToMaybe();99 comptime implicitIntLitToMaybe();
100}100}
101fn implicitIntLitToMaybe() void {101fn implicitIntLitToMaybe() void {
102 const f: ?i32 = 1;102 const f: ?i32 = 1;
103 const g: %?i32 = 1;103 const g: error!?i32 = 1;
104}104}
105105
106106
107test "return null from fn() %?&T" {107test "return null from fn() error!?&T" {
108 const a = returnNullFromMaybeTypeErrorRef();108 const a = returnNullFromMaybeTypeErrorRef();
109 const b = returnNullLitFromMaybeTypeErrorRef();109 const b = returnNullLitFromMaybeTypeErrorRef();
110 assert((try a) == null and (try b) == null);110 assert((try a) == null and (try b) == null);
111}111}
112fn returnNullFromMaybeTypeErrorRef() !?&A {112fn returnNullFromMaybeTypeErrorRef() error!?&A {
113 const a: ?&A = null;113 const a: ?&A = null;
114 return a;114 return a;
115}115}
116fn returnNullLitFromMaybeTypeErrorRef() !?&A {116fn returnNullLitFromMaybeTypeErrorRef() error!?&A {
117 return null;117 return null;
118}118}
119119
...@@ -160,7 +160,7 @@ fn castToMaybeSlice() ?[]const u8 {...@@ -160,7 +160,7 @@ fn castToMaybeSlice() ?[]const u8 {
160}160}
161161
162162
163test "implicitly cast from [0]T to %[]T" {163test "implicitly cast from [0]T to error![]T" {
164 testCastZeroArrayToErrSliceMut();164 testCastZeroArrayToErrSliceMut();
165 comptime testCastZeroArrayToErrSliceMut();165 comptime testCastZeroArrayToErrSliceMut();
166}166}
...@@ -169,11 +169,11 @@ fn testCastZeroArrayToErrSliceMut() void {...@@ -169,11 +169,11 @@ fn testCastZeroArrayToErrSliceMut() void {
169 assert((gimmeErrOrSlice() catch unreachable).len == 0);169 assert((gimmeErrOrSlice() catch unreachable).len == 0);
170}170}
171171
172fn gimmeErrOrSlice() ![]u8 {172fn gimmeErrOrSlice() error![]u8 {
173 return []u8{};173 return []u8{};
174}174}
175175
176test "peer type resolution: [0]u8, []const u8, and %[]u8" {176test "peer type resolution: [0]u8, []const u8, and error![]u8" {
177 {177 {
178 var data = "hi";178 var data = "hi";
179 const slice = data[0..];179 const slice = data[0..];
...@@ -187,7 +187,7 @@ test "peer type resolution: [0]u8, []const u8, and %[]u8" {...@@ -187,7 +187,7 @@ test "peer type resolution: [0]u8, []const u8, and %[]u8" {
187 assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);187 assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
188 }188 }
189}189}
190fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) ![]u8 {190fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) error![]u8 {
191 if (a) {191 if (a) {
192 return []u8{};192 return []u8{};
193 }193 }
...@@ -229,7 +229,7 @@ fn foo(args: ...) void {...@@ -229,7 +229,7 @@ fn foo(args: ...) void {
229229
230230
231test "peer type resolution: error and [N]T" {231test "peer type resolution: error and [N]T" {
232 // TODO: implicit %T to %U where T can implicitly cast to U232 // TODO: implicit error!T to error!U where T can implicitly cast to U
233 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));233 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
234 //comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));234 //comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
235235
...@@ -237,13 +237,13 @@ test "peer type resolution: error and [N]T" {...@@ -237,13 +237,13 @@ test "peer type resolution: error and [N]T" {
237 comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));237 comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
238}238}
239239
240//fn testPeerErrorAndArray(x: u8) ![]const u8 {240//fn testPeerErrorAndArray(x: u8) error![]const u8 {
241// return switch (x) {241// return switch (x) {
242// 0x00 => "OK",242// 0x00 => "OK",
243// else => error.BadValue,243// else => error.BadValue,
244// };244// };
245//}245//}
246fn testPeerErrorAndArray2(x: u8) ![]const u8 {246fn testPeerErrorAndArray2(x: u8) error![]const u8 {
247 return switch (x) {247 return switch (x) {
248 0x00 => "OK",248 0x00 => "OK",
249 0x01 => "OKK",249 0x01 => "OKK",
test/cases/enum_with_members.zig+1-1
...@@ -6,7 +6,7 @@ const ET = union(enum) {...@@ -6,7 +6,7 @@ const ET = union(enum) {
6 SINT: i32,6 SINT: i32,
7 UINT: u32,7 UINT: u32,
88
9 pub fn print(a: &const ET, buf: []u8) !usize {9 pub fn print(a: &const ET, buf: []u8) error!usize {
10 return switch (*a) {10 return switch (*a) {
11 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),11 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
12 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),12 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
test/cases/error.zig+7-7
...@@ -1,16 +1,16 @@...@@ -1,16 +1,16 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
33
4pub fn foo() !i32 {4pub fn foo() error!i32 {
5 const x = try bar();5 const x = try bar();
6 return x + 1;6 return x + 1;
7}7}
88
9pub fn bar() !i32 {9pub fn bar() error!i32 {
10 return 13;10 return 13;
11}11}
1212
13pub fn baz() !i32 {13pub fn baz() error!i32 {
14 const y = foo() catch 1234;14 const y = foo() catch 1234;
15 return y + 1;15 return y + 1;
16}16}
...@@ -50,7 +50,7 @@ test "error binary operator" {...@@ -50,7 +50,7 @@ test "error binary operator" {
50 assert(a == 3);50 assert(a == 3);
51 assert(b == 10);51 assert(b == 10);
52}52}
53fn errBinaryOperatorG(x: bool) !isize {53fn errBinaryOperatorG(x: bool) error!isize {
54 return if (x) error.ItBroke else isize(10);54 return if (x) error.ItBroke else isize(10);
55}55}
5656
...@@ -59,18 +59,18 @@ test "unwrap simple value from error" {...@@ -59,18 +59,18 @@ test "unwrap simple value from error" {
59 const i = unwrapSimpleValueFromErrorDo() catch unreachable;59 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
60 assert(i == 13);60 assert(i == 13);
61}61}
62fn unwrapSimpleValueFromErrorDo() %isize { return 13; }62fn unwrapSimpleValueFromErrorDo() error!isize { return 13; }
6363
6464
65test "error return in assignment" {65test "error return in assignment" {
66 doErrReturnInAssignment() catch unreachable;66 doErrReturnInAssignment() catch unreachable;
67}67}
6868
69fn doErrReturnInAssignment() !void {69fn doErrReturnInAssignment() error!void {
70 var x : i32 = undefined;70 var x : i32 = undefined;
71 x = try makeANonErr();71 x = try makeANonErr();
72}72}
7373
74fn makeANonErr() !i32 {74fn makeANonErr() error!i32 {
75 return 1;75 return 1;
76}76}
test/cases/ir_block_deps.zig+1-1
...@@ -11,7 +11,7 @@ fn foo(id: u64) !i32 {...@@ -11,7 +11,7 @@ fn foo(id: u64) !i32 {
11 };11 };
12}12}
1313
14fn getErrInt() %i32 { return 0; }14fn getErrInt() error!i32 { return 0; }
1515
16test "ir block deps" {16test "ir block deps" {
17 assert((foo(1) catch unreachable) == 0);17 assert((foo(1) catch unreachable) == 0);
test/cases/misc.zig+4-4
...@@ -262,7 +262,7 @@ test "generic malloc free" {...@@ -262,7 +262,7 @@ test "generic malloc free" {
262 memFree(u8, a);262 memFree(u8, a);
263}263}
264const some_mem : [100]u8 = undefined;264const some_mem : [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) ![]T {265fn memAlloc(comptime T: type, n: usize) error![]T {
266 return @ptrCast(&T, &some_mem[0])[0..n];266 return @ptrCast(&T, &some_mem[0])[0..n];
267}267}
268fn memFree(comptime T: type, memory: []T) void { }268fn memFree(comptime T: type, memory: []T) void { }
...@@ -419,7 +419,7 @@ test "cast slice to u8 slice" {...@@ -419,7 +419,7 @@ test "cast slice to u8 slice" {
419test "pointer to void return type" {419test "pointer to void return type" {
420 testPointerToVoidReturnType() catch unreachable;420 testPointerToVoidReturnType() catch unreachable;
421}421}
422fn testPointerToVoidReturnType() !void {422fn testPointerToVoidReturnType() error!void {
423 const a = testPointerToVoidReturnType2();423 const a = testPointerToVoidReturnType2();
424 return *a;424 return *a;
425}425}
...@@ -475,8 +475,8 @@ test "@typeId" {...@@ -475,8 +475,8 @@ test "@typeId" {
475 assert(@typeId(@typeOf(undefined)) == Tid.UndefinedLiteral);475 assert(@typeId(@typeOf(undefined)) == Tid.UndefinedLiteral);
476 assert(@typeId(@typeOf(null)) == Tid.NullLiteral);476 assert(@typeId(@typeOf(null)) == Tid.NullLiteral);
477 assert(@typeId(?i32) == Tid.Nullable);477 assert(@typeId(?i32) == Tid.Nullable);
478 assert(@typeId(%i32) == Tid.ErrorUnion);478 assert(@typeId(error!i32) == Tid.ErrorUnion);
479 assert(@typeId(error) == Tid.Error);479 assert(@typeId(error) == Tid.ErrorSet);
480 assert(@typeId(AnEnum) == Tid.Enum);480 assert(@typeId(AnEnum) == Tid.Enum);
481 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);481 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
482 assert(@typeId(AUnionEnum) == Tid.Union);482 assert(@typeId(AUnionEnum) == Tid.Union);
test/cases/reflection.zig+1-1
...@@ -5,7 +5,7 @@ test "reflection: array, pointer, nullable, error union type child" {...@@ -5,7 +5,7 @@ test "reflection: array, pointer, nullable, error union type child" {
5 comptime {5 comptime {
6 assert(([10]u8).Child == u8);6 assert(([10]u8).Child == u8);
7 assert((&u8).Child == u8);7 assert((&u8).Child == u8);
8 assert((%u8).Child == u8);8 assert((error!u8).Payload == u8);
9 assert((?u8).Child == u8);9 assert((?u8).Child == u8);
10 }10 }
11}11}
test/cases/switch.zig+1-1
...@@ -225,7 +225,7 @@ fn switchWithUnreachable(x: i32) i32 {...@@ -225,7 +225,7 @@ fn switchWithUnreachable(x: i32) i32 {
225 return 10;225 return 10;
226}226}
227227
228fn return_a_number() !i32 {228fn return_a_number() error!i32 {
229 return 1;229 return 1;
230}230}
231231
test/cases/switch_prong_err_enum.zig+2-2
...@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;...@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
22
3var read_count: u64 = 0;3var read_count: u64 = 0;
44
5fn readOnce() !u64 {5fn readOnce() error!u64 {
6 read_count += 1;6 read_count += 1;
7 return read_count;7 return read_count;
8}8}
...@@ -12,7 +12,7 @@ const FormValue = union(enum) {...@@ -12,7 +12,7 @@ const FormValue = union(enum) {
12 Other: bool,12 Other: bool,
13};13};
1414
15fn doThing(form_id: u64) !FormValue {15fn doThing(form_id: u64) error!FormValue {
16 return switch (form_id) {16 return switch (form_id) {
17 17 => FormValue { .Address = try readOnce() },17 17 => FormValue { .Address = try readOnce() },
18 else => error.InvalidDebugInfo,18 else => error.InvalidDebugInfo,
test/cases/try.zig+2-2
...@@ -17,7 +17,7 @@ fn tryOnErrorUnionImpl() void {...@@ -17,7 +17,7 @@ fn tryOnErrorUnionImpl() void {
17 assert(x == 11);17 assert(x == 11);
18}18}
1919
20fn returnsTen() !i32 {20fn returnsTen() error!i32 {
21 return 10;21 return 10;
22}22}
2323
...@@ -29,7 +29,7 @@ test "try without vars" {...@@ -29,7 +29,7 @@ test "try without vars" {
29 assert(result2 == 1);29 assert(result2 == 1);
30}30}
3131
32fn failIfTrue(ok: bool) !void {32fn failIfTrue(ok: bool) error!void {
33 if (ok) {33 if (ok) {
34 return error.ItBroke;34 return error.ItBroke;
35 } else {35 } else {
test/cases/union.zig+1-1
...@@ -13,7 +13,7 @@ const Agg = struct {...@@ -13,7 +13,7 @@ const Agg = struct {
13const v1 = Value { .Int = 1234 };13const v1 = Value { .Int = 1234 };
14const v2 = Value { .Array = []u8{3} ** 9 };14const v2 = Value { .Array = []u8{3} ** 9 };
1515
16const err = (%Agg)(Agg {16const err = (error!Agg)(Agg {
17 .val1 = v1,17 .val1 = v1,
18 .val2 = v2,18 .val2 = v2,
19});19});
test/cases/while.zig+4-4
...@@ -50,7 +50,7 @@ fn runContinueAndBreakTest() void {...@@ -50,7 +50,7 @@ fn runContinueAndBreakTest() void {
50test "return with implicit cast from while loop" {50test "return with implicit cast from while loop" {
51 returnWithImplicitCastFromWhileLoopTest() catch unreachable;51 returnWithImplicitCastFromWhileLoopTest() catch unreachable;
52}52}
53fn returnWithImplicitCastFromWhileLoopTest() !void {53fn returnWithImplicitCastFromWhileLoopTest() error!void {
54 while (true) {54 while (true) {
55 return;55 return;
56 }56 }
...@@ -116,7 +116,7 @@ test "while with error union condition" {...@@ -116,7 +116,7 @@ test "while with error union condition" {
116}116}
117117
118var numbers_left: i32 = undefined;118var numbers_left: i32 = undefined;
119fn getNumberOrErr() !i32 {119fn getNumberOrErr() error!i32 {
120 return if (numbers_left == 0)120 return if (numbers_left == 0)
121 error.OutOfNumbers121 error.OutOfNumbers
122 else x: {122 else x: {
...@@ -204,7 +204,7 @@ fn testContinueOuter() void {...@@ -204,7 +204,7 @@ fn testContinueOuter() void {
204204
205fn returnNull() ?i32 { return null; }205fn returnNull() ?i32 { return null; }
206fn returnMaybe(x: i32) ?i32 { return x; }206fn returnMaybe(x: i32) ?i32 { return x; }
207fn returnError() %i32 { return error.YouWantedAnError; }207fn returnError() error!i32 { return error.YouWantedAnError; }
208fn returnSuccess(x: i32) %i32 { return x; }208fn returnSuccess(x: i32) error!i32 { return x; }
209fn returnFalse() bool { return false; }209fn returnFalse() bool { return false; }
210fn returnTrue() bool { return true; }210fn returnTrue() bool { return true; }