authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-01 10:23:25-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-01 10:23:25-05:00
log13b36d458f6ba45fdda1c1510e056a7012fb3fff
tree26afe03e50c7206f390ff44b4347bd493cfa067e
parent5f518dbeb952186b7c11777b2454256c8c4fb9ac

*WIP* error sets - fix implicit cast


8 files changed, 92 insertions(+), 55 deletions(-)

TODO+2-1
...@@ -2,4 +2,5 @@ sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find .. -name "*.zig")...@@ -2,4 +2,5 @@ sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find .. -name "*.zig")
22
3comptime assert(error{} ! i32 == i32);3comptime assert(error{} ! i32 == i32);
44
55// TODO this is an explicit cast and should actually coerce the type
6 erorr set casting
src/analyze.cpp+38-9
...@@ -1274,7 +1274,7 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {...@@ -1274,7 +1274,7 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1274 zig_unreachable();1274 zig_unreachable();
1275}1275}
12761276
1277static TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry) {1277TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry) {
1278 TypeTableEntry *err_set_type = new_type_table_entry(TypeTableEntryIdErrorSet);1278 TypeTableEntry *err_set_type = new_type_table_entry(TypeTableEntryIdErrorSet);
1279 buf_resize(&err_set_type->name, 0);1279 buf_resize(&err_set_type->name, 0);
1280 buf_appendf(&err_set_type->name, "%s.errors", buf_ptr(&fn_entry->symbol_name));1280 buf_appendf(&err_set_type->name, "%s.errors", buf_ptr(&fn_entry->symbol_name));
...@@ -3366,7 +3366,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *so...@@ -3366,7 +3366,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *so
3366 g->tld_ref_source_node_stack.pop();3366 g->tld_ref_source_node_stack.pop();
3367}3367}
33683368
3369bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) {3369bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
3370 if (expected_type == actual_type)3370 if (expected_type == actual_type)
3371 return true;3371 return true;
33723372
...@@ -3379,7 +3379,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -3379,7 +3379,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
3379 actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count &&3379 actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count &&
3380 actual_type->data.pointer.alignment >= expected_type->data.pointer.alignment)3380 actual_type->data.pointer.alignment >= expected_type->data.pointer.alignment)
3381 {3381 {
3382 return types_match_const_cast_only(expected_type->data.pointer.child_type,3382 return types_match_const_cast_only(g, expected_type->data.pointer.child_type,
3383 actual_type->data.pointer.child_type);3383 actual_type->data.pointer.child_type);
3384 }3384 }
33853385
...@@ -3397,7 +3397,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -3397,7 +3397,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
3397 actual_ptr_type->data.pointer.unaligned_bit_count == expected_ptr_type->data.pointer.unaligned_bit_count &&3397 actual_ptr_type->data.pointer.unaligned_bit_count == expected_ptr_type->data.pointer.unaligned_bit_count &&
3398 actual_ptr_type->data.pointer.alignment >= expected_ptr_type->data.pointer.alignment)3398 actual_ptr_type->data.pointer.alignment >= expected_ptr_type->data.pointer.alignment)
3399 {3399 {
3400 return types_match_const_cast_only(expected_ptr_type->data.pointer.child_type,3400 return types_match_const_cast_only(g, expected_ptr_type->data.pointer.child_type,
3401 actual_ptr_type->data.pointer.child_type);3401 actual_ptr_type->data.pointer.child_type);
3402 }3402 }
3403 }3403 }
...@@ -3406,7 +3406,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -3406,7 +3406,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
3406 if (expected_type->id == TypeTableEntryIdMaybe &&3406 if (expected_type->id == TypeTableEntryIdMaybe &&
3407 actual_type->id == TypeTableEntryIdMaybe)3407 actual_type->id == TypeTableEntryIdMaybe)
3408 {3408 {
3409 return types_match_const_cast_only(3409 return types_match_const_cast_only(g,
3410 expected_type->data.maybe.child_type,3410 expected_type->data.maybe.child_type,
3411 actual_type->data.maybe.child_type);3411 actual_type->data.maybe.child_type);
3412 }3412 }
...@@ -3415,14 +3415,43 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -3415,14 +3415,43 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
3415 if (expected_type->id == TypeTableEntryIdErrorUnion &&3415 if (expected_type->id == TypeTableEntryIdErrorUnion &&
3416 actual_type->id == TypeTableEntryIdErrorUnion)3416 actual_type->id == TypeTableEntryIdErrorUnion)
3417 {3417 {
3418 return types_match_const_cast_only(3418 return types_match_const_cast_only(g,
3419 expected_type->data.error_union.payload_type,3419 expected_type->data.error_union.payload_type,
3420 actual_type->data.error_union.payload_type) &&3420 actual_type->data.error_union.payload_type) &&
3421 types_match_const_cast_only(3421 types_match_const_cast_only(g,
3422 expected_type->data.error_union.err_set_type,3422 expected_type->data.error_union.err_set_type,
3423 actual_type->data.error_union.err_set_type);3423 actual_type->data.error_union.err_set_type);
3424 }3424 }
34253425
3426 // error set
3427 if (expected_type->id == TypeTableEntryIdErrorSet &&
3428 actual_type->id == TypeTableEntryIdErrorSet)
3429 {
3430 TypeTableEntry *contained_set = actual_type;
3431 TypeTableEntry *container_set = expected_type;
3432
3433 if (container_set == g->builtin_types.entry_global_error_set ||
3434 container_set->data.error_set.infer_fn != nullptr)
3435 {
3436 return true;
3437 }
3438
3439 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(g->errors_by_index.length);
3440 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) {
3441 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i];
3442 errors[error_entry->value] = error_entry;
3443 }
3444 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) {
3445 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i];
3446 ErrorTableEntry *error_entry = errors[contained_error_entry->value];
3447 if (error_entry == nullptr) {
3448 return false;
3449 }
3450 }
3451 free(errors);
3452 return true;
3453 }
3454
3426 // fn3455 // fn
3427 if (expected_type->id == TypeTableEntryIdFn &&3456 if (expected_type->id == TypeTableEntryIdFn &&
3428 actual_type->id == TypeTableEntryIdFn)3457 actual_type->id == TypeTableEntryIdFn)
...@@ -3441,7 +3470,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -3441,7 +3470,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
3441 }3470 }
3442 if (!expected_type->data.fn.is_generic &&3471 if (!expected_type->data.fn.is_generic &&
3443 actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable &&3472 actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable &&
3444 !types_match_const_cast_only(3473 !types_match_const_cast_only(g,
3445 expected_type->data.fn.fn_type_id.return_type,3474 expected_type->data.fn.fn_type_id.return_type,
3446 actual_type->data.fn.fn_type_id.return_type))3475 actual_type->data.fn.fn_type_id.return_type))
3447 {3476 {
...@@ -3460,7 +3489,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -3460,7 +3489,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
3460 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i];3489 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i];
3461 FnTypeParamInfo *expected_param_info = &expected_type->data.fn.fn_type_id.param_info[i];3490 FnTypeParamInfo *expected_param_info = &expected_type->data.fn.fn_type_id.param_info[i];
34623491
3463 if (!types_match_const_cast_only(actual_param_info->type, expected_param_info->type)) {3492 if (!types_match_const_cast_only(g, actual_param_info->type, expected_param_info->type)) {
3464 return false;3493 return false;
3465 }3494 }
34663495
src/analyze.hpp+2-1
...@@ -46,7 +46,7 @@ bool type_has_bits(TypeTableEntry *type_entry);...@@ -46,7 +46,7 @@ bool type_has_bits(TypeTableEntry *type_entry);
46ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);46ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
4747
4848
49bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);49bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type);
50VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);50VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);
51Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);51Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
52void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node);52void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node);
...@@ -189,5 +189,6 @@ ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);...@@ -189,5 +189,6 @@ ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);
189TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g);189TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g);
190void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry);190void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry);
191191
192TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry);
192193
193#endif194#endif
src/ir.cpp+36-37
...@@ -6375,7 +6375,7 @@ enum ImplicitCastMatchResult {...@@ -6375,7 +6375,7 @@ enum ImplicitCastMatchResult {
6375static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type,6375static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type,
6376 TypeTableEntry *actual_type, IrInstruction *value)6376 TypeTableEntry *actual_type, IrInstruction *value)
6377{6377{
6378 if (types_match_const_cast_only(expected_type, actual_type)) {6378 if (types_match_const_cast_only(ira->codegen, expected_type, actual_type)) {
6379 return ImplicitCastMatchResultYes;6379 return ImplicitCastMatchResultYes;
6380 }6380 }
63816381
...@@ -6412,13 +6412,6 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6412,13 +6412,6 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6412 return ImplicitCastMatchResultYes;6412 return ImplicitCastMatchResultYes;
6413 }6413 }
64146414
6415 // implicit conversion from error set to another error set
6416 if (expected_type->id == TypeTableEntryIdErrorSet &&
6417 actual_type->id == TypeTableEntryIdErrorSet)
6418 {
6419 return ImplicitCastMatchResultYes;
6420 }
6421
6422 // implicit conversion from T to U!?T6415 // implicit conversion from T to U!?T
6423 if (expected_type->id == TypeTableEntryIdErrorUnion &&6416 if (expected_type->id == TypeTableEntryIdErrorUnion &&
6424 expected_type->data.error_union.payload_type->id == TypeTableEntryIdMaybe &&6417 expected_type->data.error_union.payload_type->id == TypeTableEntryIdMaybe &&
...@@ -6463,7 +6456,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6463,7 +6456,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6463 assert(ptr_type->id == TypeTableEntryIdPointer);6456 assert(ptr_type->id == TypeTableEntryIdPointer);
64646457
6465 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&6458 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
6466 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))6459 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
6467 {6460 {
6468 return ImplicitCastMatchResultYes;6461 return ImplicitCastMatchResultYes;
6469 }6462 }
...@@ -6482,7 +6475,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6482,7 +6475,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6482 TypeTableEntry *array_type = actual_type->data.pointer.child_type;6475 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
64836476
6484 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&6477 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
6485 types_match_const_cast_only(ptr_type->data.pointer.child_type, array_type->data.array.child_type))6478 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, array_type->data.array.child_type))
6486 {6479 {
6487 return ImplicitCastMatchResultYes;6480 return ImplicitCastMatchResultYes;
6488 }6481 }
...@@ -6498,7 +6491,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6498,7 +6491,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6498 expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;6491 expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
6499 assert(ptr_type->id == TypeTableEntryIdPointer);6492 assert(ptr_type->id == TypeTableEntryIdPointer);
6500 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&6493 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
6501 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))6494 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
6502 {6495 {
6503 return ImplicitCastMatchResultYes;6496 return ImplicitCastMatchResultYes;
6504 }6497 }
...@@ -6513,7 +6506,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6513,7 +6506,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6513 expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;6506 expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
6514 assert(ptr_type->id == TypeTableEntryIdPointer);6507 assert(ptr_type->id == TypeTableEntryIdPointer);
6515 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&6508 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
6516 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))6509 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
6517 {6510 {
6518 return ImplicitCastMatchResultYes;6511 return ImplicitCastMatchResultYes;
6519 }6512 }
...@@ -6593,7 +6586,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -6593,7 +6586,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
6593 // implicitly take a const pointer to something6586 // implicitly take a const pointer to something
6594 if (!type_requires_comptime(actual_type)) {6587 if (!type_requires_comptime(actual_type)) {
6595 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);6588 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
6596 if (types_match_const_cast_only(expected_type, const_ptr_actual)) {6589 if (types_match_const_cast_only(ira->codegen, expected_type, const_ptr_actual)) {
6597 return ImplicitCastMatchResultYes;6590 return ImplicitCastMatchResultYes;
6598 }6591 }
6599 }6592 }
...@@ -6769,11 +6762,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6769,11 +6762,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6769 }6762 }
6770 }6763 }
67716764
6772 if (types_match_const_cast_only(prev_type, cur_type)) {6765 if (types_match_const_cast_only(ira->codegen, prev_type, cur_type)) {
6773 continue;6766 continue;
6774 }6767 }
67756768
6776 if (types_match_const_cast_only(cur_type, prev_type)) {6769 if (types_match_const_cast_only(ira->codegen, cur_type, prev_type)) {
6777 prev_inst = cur_inst;6770 prev_inst = cur_inst;
6778 continue;6771 continue;
6779 }6772 }
...@@ -6796,26 +6789,26 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6796,26 +6789,26 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6796 }6789 }
67976790
6798 if (prev_type->id == TypeTableEntryIdErrorUnion &&6791 if (prev_type->id == TypeTableEntryIdErrorUnion &&
6799 types_match_const_cast_only(prev_type->data.error_union.payload_type, cur_type))6792 types_match_const_cast_only(ira->codegen, prev_type->data.error_union.payload_type, cur_type))
6800 {6793 {
6801 continue;6794 continue;
6802 }6795 }
68036796
6804 if (cur_type->id == TypeTableEntryIdErrorUnion &&6797 if (cur_type->id == TypeTableEntryIdErrorUnion &&
6805 types_match_const_cast_only(cur_type->data.error_union.payload_type, prev_type))6798 types_match_const_cast_only(ira->codegen, cur_type->data.error_union.payload_type, prev_type))
6806 {6799 {
6807 prev_inst = cur_inst;6800 prev_inst = cur_inst;
6808 continue;6801 continue;
6809 }6802 }
68106803
6811 if (prev_type->id == TypeTableEntryIdMaybe &&6804 if (prev_type->id == TypeTableEntryIdMaybe &&
6812 types_match_const_cast_only(prev_type->data.maybe.child_type, cur_type))6805 types_match_const_cast_only(ira->codegen, prev_type->data.maybe.child_type, cur_type))
6813 {6806 {
6814 continue;6807 continue;
6815 }6808 }
68166809
6817 if (cur_type->id == TypeTableEntryIdMaybe &&6810 if (cur_type->id == TypeTableEntryIdMaybe &&
6818 types_match_const_cast_only(cur_type->data.maybe.child_type, prev_type))6811 types_match_const_cast_only(ira->codegen, cur_type->data.maybe.child_type, prev_type))
6819 {6812 {
6820 prev_inst = cur_inst;6813 prev_inst = cur_inst;
6821 continue;6814 continue;
...@@ -6853,7 +6846,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6853,7 +6846,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
68536846
6854 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&6847 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
6855 cur_type->data.array.len != prev_type->data.array.len &&6848 cur_type->data.array.len != prev_type->data.array.len &&
6856 types_match_const_cast_only(cur_type->data.array.child_type, prev_type->data.array.child_type))6849 types_match_const_cast_only(ira->codegen, cur_type->data.array.child_type, prev_type->data.array.child_type))
6857 {6850 {
6858 convert_to_const_slice = true;6851 convert_to_const_slice = true;
6859 prev_inst = cur_inst;6852 prev_inst = cur_inst;
...@@ -6862,7 +6855,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6862,7 +6855,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
68626855
6863 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&6856 if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
6864 cur_type->data.array.len != prev_type->data.array.len &&6857 cur_type->data.array.len != prev_type->data.array.len &&
6865 types_match_const_cast_only(prev_type->data.array.child_type, cur_type->data.array.child_type))6858 types_match_const_cast_only(ira->codegen, prev_type->data.array.child_type, cur_type->data.array.child_type))
6866 {6859 {
6867 convert_to_const_slice = true;6860 convert_to_const_slice = true;
6868 continue;6861 continue;
...@@ -6871,7 +6864,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6871,7 +6864,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6871 if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&6864 if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&
6872 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||6865 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
6873 cur_type->data.array.len == 0) &&6866 cur_type->data.array.len == 0) &&
6874 types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,6867 types_match_const_cast_only(ira->codegen, prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
6875 cur_type->data.array.child_type))6868 cur_type->data.array.child_type))
6876 {6869 {
6877 convert_to_const_slice = false;6870 convert_to_const_slice = false;
...@@ -6881,7 +6874,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -6881,7 +6874,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
6881 if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&6874 if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&
6882 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||6875 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
6883 prev_type->data.array.len == 0) &&6876 prev_type->data.array.len == 0) &&
6884 types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,6877 types_match_const_cast_only(ira->codegen, cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
6885 prev_type->data.array.child_type))6878 prev_type->data.array.child_type))
6886 {6879 {
6887 prev_inst = cur_inst;6880 prev_inst = cur_inst;
...@@ -7449,6 +7442,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction...@@ -7449,6 +7442,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
7449 return result;7442 return result;
7450}7443}
74517444
7445// TODO this is an explicit cast and should actually coerce the type
7452static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,7446static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
7453 TypeTableEntry *wanted_type)7447 TypeTableEntry *wanted_type)
7454{7448{
...@@ -7999,7 +7993,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -7999,7 +7993,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
7999 return value;7993 return value;
80007994
8001 // explicit match or non-const to const7995 // explicit match or non-const to const
8002 if (types_match_const_cast_only(wanted_type, actual_type)) {7996 if (types_match_const_cast_only(ira->codegen, wanted_type, actual_type)) {
8003 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);7997 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
8004 }7998 }
80057999
...@@ -8045,7 +8039,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8045,7 +8039,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8045 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;8039 TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
8046 assert(ptr_type->id == TypeTableEntryIdPointer);8040 assert(ptr_type->id == TypeTableEntryIdPointer);
8047 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8041 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8048 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))8042 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
8049 {8043 {
8050 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);8044 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
8051 }8045 }
...@@ -8063,7 +8057,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8063,7 +8057,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8063 TypeTableEntry *array_type = actual_type->data.pointer.child_type;8057 TypeTableEntry *array_type = actual_type->data.pointer.child_type;
80648058
8065 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&8059 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
8066 types_match_const_cast_only(ptr_type->data.pointer.child_type, array_type->data.array.child_type))8060 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, array_type->data.array.child_type))
8067 {8061 {
8068 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);8062 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
8069 }8063 }
...@@ -8079,7 +8073,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8079,7 +8073,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8079 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;8073 wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
8080 assert(ptr_type->id == TypeTableEntryIdPointer);8074 assert(ptr_type->id == TypeTableEntryIdPointer);
8081 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8075 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8082 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))8076 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
8083 {8077 {
8084 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);8078 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
8085 if (type_is_invalid(cast1->value.type))8079 if (type_is_invalid(cast1->value.type))
...@@ -8102,7 +8096,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8102,7 +8096,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8102 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;8096 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
8103 assert(ptr_type->id == TypeTableEntryIdPointer);8097 assert(ptr_type->id == TypeTableEntryIdPointer);
8104 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8098 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8105 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))8099 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
8106 {8100 {
8107 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);8101 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
8108 if (type_is_invalid(cast1->value.type))8102 if (type_is_invalid(cast1->value.type))
...@@ -8164,7 +8158,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8164,7 +8158,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
81648158
8165 // explicit cast from child type of maybe type to maybe type8159 // explicit cast from child type of maybe type to maybe type
8166 if (wanted_type->id == TypeTableEntryIdMaybe) {8160 if (wanted_type->id == TypeTableEntryIdMaybe) {
8167 if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {8161 if (types_match_const_cast_only(ira->codegen, wanted_type->data.maybe.child_type, actual_type)) {
8168 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);8162 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
8169 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||8163 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
8170 actual_type->id == TypeTableEntryIdNumLitFloat)8164 actual_type->id == TypeTableEntryIdNumLitFloat)
...@@ -8186,7 +8180,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8186,7 +8180,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
81868180
8187 // explicit cast from child type of error type to error type8181 // explicit cast from child type of error type to error type
8188 if (wanted_type->id == TypeTableEntryIdErrorUnion) {8182 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
8189 if (types_match_const_cast_only(wanted_type->data.error_union.payload_type, actual_type)) {8183 if (types_match_const_cast_only(ira->codegen, wanted_type->data.error_union.payload_type, actual_type)) {
8190 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);8184 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
8191 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||8185 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||
8192 actual_type->id == TypeTableEntryIdNumLitFloat)8186 actual_type->id == TypeTableEntryIdNumLitFloat)
...@@ -8208,7 +8202,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8208,7 +8202,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8208 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;8202 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
8209 assert(ptr_type->id == TypeTableEntryIdPointer);8203 assert(ptr_type->id == TypeTableEntryIdPointer);
8210 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&8204 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
8211 types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))8205 types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
8212 {8206 {
8213 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);8207 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
8214 if (type_is_invalid(cast1->value.type))8208 if (type_is_invalid(cast1->value.type))
...@@ -8235,7 +8229,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8235,7 +8229,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8235 actual_type->id != TypeTableEntryIdMaybe)8229 actual_type->id != TypeTableEntryIdMaybe)
8236 {8230 {
8237 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;8231 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
8238 if (types_match_const_cast_only(wanted_child_type, actual_type) ||8232 if (types_match_const_cast_only(ira->codegen, wanted_child_type, actual_type) ||
8239 actual_type->id == TypeTableEntryIdNullLit ||8233 actual_type->id == TypeTableEntryIdNullLit ||
8240 actual_type->id == TypeTableEntryIdNumLitInt ||8234 actual_type->id == TypeTableEntryIdNumLitInt ||
8241 actual_type->id == TypeTableEntryIdNumLitFloat)8235 actual_type->id == TypeTableEntryIdNumLitFloat)
...@@ -8385,7 +8379,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -8385,7 +8379,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
8385 // explicit cast from something to const pointer of it8379 // explicit cast from something to const pointer of it
8386 if (!type_requires_comptime(actual_type)) {8380 if (!type_requires_comptime(actual_type)) {
8387 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);8381 TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
8388 if (types_match_const_cast_only(wanted_type, const_ptr_actual)) {8382 if (types_match_const_cast_only(ira->codegen, wanted_type, const_ptr_actual)) {
8389 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);8383 return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);
8390 }8384 }
8391 }8385 }
...@@ -10386,12 +10380,17 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -10386,12 +10380,17 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1038610380
10387 {10381 {
10388 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;10382 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
10389 TypeTableEntry *return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);10383 TypeTableEntry *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
10390 if (type_is_invalid(return_type))10384 if (type_is_invalid(specified_return_type))
10391 return ira->codegen->builtin_types.entry_invalid;10385 return ira->codegen->builtin_types.entry_invalid;
10392 inst_fn_type_id.return_type = return_type;10386 if (fn_proto_node->data.fn_proto.auto_err_set) {
10387 TypeTableEntry *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn);
10388 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type);
10389 } else {
10390 inst_fn_type_id.return_type = specified_return_type;
10391 }
1039310392
10394 if (type_requires_comptime(return_type)) {10393 if (type_requires_comptime(specified_return_type)) {
10395 // Throw out our work and call the function as if it were comptime.10394 // Throw out our work and call the function as if it were comptime.
10396 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, true, FnInlineAuto);10395 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, true, FnInlineAuto);
10397 }10396 }
std/fmt/index.zig+1-1
...@@ -220,7 +220,7 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@...@@ -220,7 +220,7 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@
220 return formatValue(err, context, Errors, output);220 return formatValue(err, context, Errors, output);
221 }221 }
222 },222 },
223 builtin.TypeId.Error => {223 builtin.TypeId.ErrorSet => {
224 try output(context, "error.");224 try output(context, "error.");
225 return output(context, @errorName(value));225 return output(context, @errorName(value));
226 },226 },
std/io.zig+5-3
...@@ -26,7 +26,9 @@ test "import io tests" {...@@ -26,7 +26,9 @@ test "import io tests" {
26 }26 }
27}27}
2828
29pub fn getStdErr() !File {29const GetStdIoErrs = os.WindowsGetStdHandleErrs;
30
31pub fn getStdErr() GetStdIoErrs!File {
30 const handle = if (is_windows)32 const handle = if (is_windows)
31 try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)33 try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
32 else if (is_posix)34 else if (is_posix)
...@@ -36,7 +38,7 @@ pub fn getStdErr() !File {...@@ -36,7 +38,7 @@ pub fn getStdErr() !File {
36 return File.openHandle(handle);38 return File.openHandle(handle);
37}39}
3840
39pub fn getStdOut() !File {41pub fn getStdOut() GetStdIoErrs!File {
40 const handle = if (is_windows)42 const handle = if (is_windows)
41 try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)43 try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
42 else if (is_posix)44 else if (is_posix)
...@@ -46,7 +48,7 @@ pub fn getStdOut() !File {...@@ -46,7 +48,7 @@ pub fn getStdOut() !File {
46 return File.openHandle(handle);48 return File.openHandle(handle);
47}49}
4850
49pub fn getStdIn() !File {51pub fn getStdIn() GetStdIoErrs!File {
50 const handle = if (is_windows)52 const handle = if (is_windows)
51 try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)53 try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
52 else if (is_posix)54 else if (is_posix)
std/mem.zig+2-2
...@@ -40,7 +40,7 @@ pub const Allocator = struct {...@@ -40,7 +40,7 @@ pub const Allocator = struct {
40 }40 }
4141
42 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,42 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,
43 n: usize) %[]align(alignment) T43 n: usize) ![]align(alignment) T
44 {44 {
45 const byte_count = try math.mul(usize, @sizeOf(T), n);45 const byte_count = try math.mul(usize, @sizeOf(T), n);
46 const byte_slice = try self.allocFn(self, byte_count, alignment);46 const byte_slice = try self.allocFn(self, byte_count, alignment);
...@@ -56,7 +56,7 @@ pub const Allocator = struct {...@@ -56,7 +56,7 @@ pub const Allocator = struct {
56 }56 }
5757
58 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,58 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,
59 old_mem: []align(alignment) T, n: usize) %[]align(alignment) T59 old_mem: []align(alignment) T, n: usize) ![]align(alignment) T
60 {60 {
61 if (old_mem.len == 0) {61 if (old_mem.len == 0) {
62 return self.alloc(T, n);62 return self.alloc(T, n);
std/os/index.zig+6-1
...@@ -1158,7 +1158,12 @@ pub fn posix_setregid(rgid: u32, egid: u32) !void {...@@ -1158,7 +1158,12 @@ pub fn posix_setregid(rgid: u32, egid: u32) !void {
1158 };1158 };
1159}1159}
11601160
1161pub fn windowsGetStdHandle(handle_id: windows.DWORD) !windows.HANDLE {1161pub const WindowsGetStdHandleErrs = error {
1162 NoStdHandles,
1163 Unexpected,
1164};
1165
1166pub fn windowsGetStdHandle(handle_id: windows.DWORD) WindowsGetStdHandleErrs!windows.HANDLE {
1162 if (windows.GetStdHandle(handle_id)) |handle| {1167 if (windows.GetStdHandle(handle_id)) |handle| {
1163 if (handle == windows.INVALID_HANDLE_VALUE) {1168 if (handle == windows.INVALID_HANDLE_VALUE) {
1164 const err = windows.GetLastError();1169 const err = windows.GetLastError();