| ... | @@ -61,14 +61,14 @@ ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg) { | ... | @@ -61,14 +61,14 @@ ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg) { |
| 61 | return err; | 61 | return err; |
| 62 | } | 62 | } |
| 63 | | 63 | |
| 64 | ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { | 64 | ErrorMsg *add_node_error(CodeGen *g, const AstNode *node, Buf *msg) { |
| 65 | Token fake_token; | 65 | Token fake_token; |
| 66 | fake_token.start_line = node->line; | 66 | fake_token.start_line = node->line; |
| 67 | fake_token.start_column = node->column; | 67 | fake_token.start_column = node->column; |
| 68 | return add_token_error(g, node->owner, &fake_token, msg); | 68 | return add_token_error(g, node->owner, &fake_token, msg); |
| 69 | } | 69 | } |
| 70 | | 70 | |
| 71 | ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) { | 71 | ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg) { |
| 72 | Token fake_token; | 72 | Token fake_token; |
| 73 | fake_token.start_line = node->line; | 73 | fake_token.start_line = node->line; |
| 74 | fake_token.start_column = node->column; | 74 | fake_token.start_column = node->column; |
| ... | @@ -2656,7 +2656,6 @@ ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) { | ... | @@ -2656,7 +2656,6 @@ ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) { |
| 2656 | | 2656 | |
| 2657 | fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota; | 2657 | fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota; |
| 2658 | | 2658 | |
| 2659 | fn_entry->codegen = g; | | |
| 2660 | fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; | 2659 | fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; |
| 2661 | fn_entry->analyzed_executable.backward_branch_quota = &fn_entry->prealloc_backward_branch_quota; | 2660 | fn_entry->analyzed_executable.backward_branch_quota = &fn_entry->prealloc_backward_branch_quota; |
| 2662 | fn_entry->analyzed_executable.fn_entry = fn_entry; | 2661 | fn_entry->analyzed_executable.fn_entry = fn_entry; |
| ... | @@ -2784,6 +2783,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -2784,6 +2783,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2784 | } | 2783 | } |
| 2785 | } | 2784 | } |
| 2786 | } else { | 2785 | } else { |
| | 2786 | fn_table_entry->inferred_async_node = inferred_async_none; |
| 2787 | g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base); | 2787 | g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base); |
| 2788 | } | 2788 | } |
| 2789 | | 2789 | |
| ... | @@ -2805,14 +2805,11 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -2805,14 +2805,11 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2805 | g->fn_defs.append(fn_table_entry); | 2805 | g->fn_defs.append(fn_table_entry); |
| 2806 | } | 2806 | } |
| 2807 | | 2807 | |
| 2808 | switch (fn_table_entry->type_entry->data.fn.fn_type_id.cc) { | 2808 | // if the calling convention implies that it cannot be async, we save that for later |
| 2809 | case CallingConventionAsync: | 2809 | // and leave the value to be nullptr to indicate that we have not emitted possible |
| 2810 | fn_table_entry->inferred_async_node = fn_table_entry->proto_node; | 2810 | // compile errors for improperly calling async functions. |
| 2811 | break; | 2811 | if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) { |
| 2812 | case CallingConventionUnspecified: | 2812 | fn_table_entry->inferred_async_node = fn_table_entry->proto_node; |
| 2813 | break; | | |
| 2814 | default: | | |
| 2815 | fn_table_entry->inferred_async_node = inferred_async_none; | | |
| 2816 | } | 2813 | } |
| 2817 | | 2814 | |
| 2818 | if (scope_is_root_decls(tld_fn->base.parent_scope) && | 2815 | if (scope_is_root_decls(tld_fn->base.parent_scope) && |
| ... | @@ -3801,6 +3798,25 @@ bool fn_is_async(ZigFn *fn) { | ... | @@ -3801,6 +3798,25 @@ bool fn_is_async(ZigFn *fn) { |
| 3801 | return fn->inferred_async_node != inferred_async_none; | 3798 | return fn->inferred_async_node != inferred_async_none; |
| 3802 | } | 3799 | } |
| 3803 | | 3800 | |
| | 3801 | static void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn) { |
| | 3802 | assert(fn->inferred_async_node != nullptr); |
| | 3803 | assert(fn->inferred_async_node != inferred_async_checking); |
| | 3804 | assert(fn->inferred_async_node != inferred_async_none); |
| | 3805 | if (fn->inferred_async_fn != nullptr) { |
| | 3806 | ErrorMsg *new_msg = add_error_note(g, msg, fn->inferred_async_node, |
| | 3807 | buf_sprintf("async function call here")); |
| | 3808 | return add_async_error_notes(g, new_msg, fn->inferred_async_fn); |
| | 3809 | } else if (fn->inferred_async_node->type == NodeTypeFnProto) { |
| | 3810 | add_error_note(g, msg, fn->inferred_async_node, |
| | 3811 | buf_sprintf("async calling convention here")); |
| | 3812 | } else if (fn->inferred_async_node->type == NodeTypeSuspend) { |
| | 3813 | add_error_note(g, msg, fn->inferred_async_node, |
| | 3814 | buf_sprintf("suspends here")); |
| | 3815 | } else { |
| | 3816 | zig_unreachable(); |
| | 3817 | } |
| | 3818 | } |
| | 3819 | |
| 3804 | // This function resolves functions being inferred async. | 3820 | // This function resolves functions being inferred async. |
| 3805 | static void analyze_fn_async(CodeGen *g, ZigFn *fn) { | 3821 | static void analyze_fn_async(CodeGen *g, ZigFn *fn) { |
| 3806 | if (fn->inferred_async_node == inferred_async_checking) { | 3822 | if (fn->inferred_async_node == inferred_async_checking) { |
| ... | @@ -3816,6 +3832,13 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn) { | ... | @@ -3816,6 +3832,13 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn) { |
| 3816 | return; | 3832 | return; |
| 3817 | } | 3833 | } |
| 3818 | fn->inferred_async_node = inferred_async_checking; | 3834 | fn->inferred_async_node = inferred_async_checking; |
| | 3835 | |
| | 3836 | bool must_not_be_async = false; |
| | 3837 | if (fn->type_entry->data.fn.fn_type_id.cc != CallingConventionUnspecified) { |
| | 3838 | must_not_be_async = true; |
| | 3839 | fn->inferred_async_node = inferred_async_none; |
| | 3840 | } |
| | 3841 | |
| 3819 | for (size_t i = 0; i < fn->call_list.length; i += 1) { | 3842 | for (size_t i = 0; i < fn->call_list.length; i += 1) { |
| 3820 | FnCall *call = &fn->call_list.at(i); | 3843 | FnCall *call = &fn->call_list.at(i); |
| 3821 | if (call->callee->type_entry->data.fn.fn_type_id.cc != CallingConventionUnspecified) | 3844 | if (call->callee->type_entry->data.fn.fn_type_id.cc != CallingConventionUnspecified) |
| ... | @@ -3828,6 +3851,15 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn) { | ... | @@ -3828,6 +3851,15 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn) { |
| 3828 | } | 3851 | } |
| 3829 | if (fn_is_async(call->callee)) { | 3852 | if (fn_is_async(call->callee)) { |
| 3830 | fn->inferred_async_node = call->source_node; | 3853 | fn->inferred_async_node = call->source_node; |
| | 3854 | fn->inferred_async_fn = call->callee; |
| | 3855 | if (must_not_be_async) { |
| | 3856 | ErrorMsg *msg = add_node_error(g, fn->proto_node, |
| | 3857 | buf_sprintf("function with calling convention '%s' cannot be async", |
| | 3858 | calling_convention_name(fn->type_entry->data.fn.fn_type_id.cc))); |
| | 3859 | add_async_error_notes(g, msg, fn); |
| | 3860 | fn->anal_state = FnAnalStateInvalid; |
| | 3861 | return; |
| | 3862 | } |
| 3831 | resolve_async_fn_frame(g, fn); | 3863 | resolve_async_fn_frame(g, fn); |
| 3832 | return; | 3864 | return; |
| 3833 | } | 3865 | } |
| ... | @@ -4451,7 +4483,7 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { | ... | @@ -4451,7 +4483,7 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { |
| 4451 | if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) { | 4483 | if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) { |
| 4452 | assert(a_val->special == ConstValSpecialStatic); | 4484 | assert(a_val->special == ConstValSpecialStatic); |
| 4453 | assert(b_val->special == ConstValSpecialStatic); | 4485 | assert(b_val->special == ConstValSpecialStatic); |
| 4454 | if (!const_values_equal(a->fn_entry->codegen, a_val, b_val)) { | 4486 | if (!const_values_equal(a->codegen, a_val, b_val)) { |
| 4455 | return false; | 4487 | return false; |
| 4456 | } | 4488 | } |
| 4457 | } else { | 4489 | } else { |