| ... | @@ -3593,33 +3593,27 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -3593,33 +3593,27 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 3593 | zig_unreachable(); | 3593 | zig_unreachable(); |
| 3594 | } | 3594 | } |
| 3595 | | 3595 | |
| 3596 | static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 3596 | static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 3597 | TypeTableEntry *expected_type, AstNode *node, FnTableEntry *fn_table_entry, TypeTableEntry *struct_type) | 3597 | TypeTableEntry *expected_type, AstNode *node, TypeTableEntry *fn_type, TypeTableEntry *struct_type) |
| 3598 | { | 3598 | { |
| 3599 | assert(node->type == NodeTypeFnCallExpr); | 3599 | assert(node->type == NodeTypeFnCallExpr); |
| 3600 | | 3600 | |
| 3601 | node->data.fn_call_expr.fn_entry = fn_table_entry; | | |
| 3602 | assert(fn_table_entry->proto_node->type == NodeTypeFnProto); | | |
| 3603 | AstNodeFnProto *fn_proto = &fn_table_entry->proto_node->data.fn_proto; | | |
| 3604 | | | |
| 3605 | // count parameters | 3601 | // count parameters |
| 3606 | int expected_param_count = fn_proto->params.length; | 3602 | int src_param_count = fn_type->data.fn.src_param_count; |
| 3607 | int actual_param_count = node->data.fn_call_expr.params.length; | 3603 | int actual_param_count = node->data.fn_call_expr.params.length; |
| 3608 | | 3604 | |
| 3609 | if (struct_type) { | 3605 | if (struct_type) { |
| 3610 | actual_param_count += 1; | 3606 | actual_param_count += 1; |
| 3611 | } | 3607 | } |
| 3612 | | 3608 | |
| 3613 | if (fn_proto->is_var_args) { | 3609 | if (fn_type->data.fn.is_var_args) { |
| 3614 | if (actual_param_count < expected_param_count) { | 3610 | if (actual_param_count < src_param_count) { |
| 3615 | add_node_error(g, node, | 3611 | add_node_error(g, node, |
| 3616 | buf_sprintf("expected at least %d arguments, got %d", | 3612 | buf_sprintf("expected at least %d arguments, got %d", src_param_count, actual_param_count)); |
| 3617 | expected_param_count, actual_param_count)); | | |
| 3618 | } | 3613 | } |
| 3619 | } else if (expected_param_count != actual_param_count) { | 3614 | } else if (src_param_count != actual_param_count) { |
| 3620 | add_node_error(g, node, | 3615 | add_node_error(g, node, |
| 3621 | buf_sprintf("expected %d arguments, got %d", | 3616 | buf_sprintf("expected %d arguments, got %d", src_param_count, actual_param_count)); |
| 3622 | expected_param_count, actual_param_count)); | | |
| 3623 | } | 3617 | } |
| 3624 | | 3618 | |
| 3625 | // analyze each parameter. in the case of a method, we already analyzed the | 3619 | // analyze each parameter. in the case of a method, we already analyzed the |
| ... | @@ -3629,19 +3623,13 @@ static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, | ... | @@ -3629,19 +3623,13 @@ static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, |
| 3629 | // determine the expected type for each parameter | 3623 | // determine the expected type for each parameter |
| 3630 | TypeTableEntry *expected_param_type = nullptr; | 3624 | TypeTableEntry *expected_param_type = nullptr; |
| 3631 | int fn_proto_i = i + (struct_type ? 1 : 0); | 3625 | int fn_proto_i = i + (struct_type ? 1 : 0); |
| 3632 | if (fn_proto_i < fn_proto->params.length) { | 3626 | if (fn_proto_i < src_param_count) { |
| 3633 | AstNode *param_decl_node = fn_proto->params.at(fn_proto_i); | 3627 | expected_param_type = fn_type->data.fn.param_types[fn_proto_i]; |
| 3634 | assert(param_decl_node->type == NodeTypeParamDecl); | | |
| 3635 | AstNode *param_type_node = param_decl_node->data.param_decl.type; | | |
| 3636 | TypeTableEntry *param_type_entry = get_resolved_expr(param_type_node)->type_entry; | | |
| 3637 | if (param_type_entry) { | | |
| 3638 | expected_param_type = unwrapped_node_type(param_type_node); | | |
| 3639 | } | | |
| 3640 | } | 3628 | } |
| 3641 | analyze_expression(g, import, context, expected_param_type, child); | 3629 | analyze_expression(g, import, context, expected_param_type, child); |
| 3642 | } | 3630 | } |
| 3643 | | 3631 | |
| 3644 | TypeTableEntry *return_type = unwrapped_node_type(fn_proto->return_type); | 3632 | TypeTableEntry *return_type = fn_type->data.fn.src_return_type; |
| 3645 | | 3633 | |
| 3646 | if (return_type->id == TypeTableEntryIdInvalid) { | 3634 | if (return_type->id == TypeTableEntryIdInvalid) { |
| 3647 | return return_type; | 3635 | return return_type; |
| ... | @@ -3654,6 +3642,17 @@ static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, | ... | @@ -3654,6 +3642,17 @@ static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, |
| 3654 | return return_type; | 3642 | return return_type; |
| 3655 | } | 3643 | } |
| 3656 | | 3644 | |
| | 3645 | static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| | 3646 | TypeTableEntry *expected_type, AstNode *node, FnTableEntry *fn_table_entry, TypeTableEntry *struct_type) |
| | 3647 | { |
| | 3648 | assert(node->type == NodeTypeFnCallExpr); |
| | 3649 | |
| | 3650 | node->data.fn_call_expr.fn_entry = fn_table_entry; |
| | 3651 | |
| | 3652 | return analyze_fn_call_ptr(g, import, context, expected_type, node, fn_table_entry->type_entry, struct_type); |
| | 3653 | |
| | 3654 | } |
| | 3655 | |
| 3657 | static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 3656 | static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 3658 | TypeTableEntry *expected_type, AstNode *node) | 3657 | TypeTableEntry *expected_type, AstNode *node) |
| 3659 | { | 3658 | { |
| ... | @@ -3761,7 +3760,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import | ... | @@ -3761,7 +3760,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import |
| 3761 | | 3760 | |
| 3762 | // function pointer | 3761 | // function pointer |
| 3763 | if (invoke_type_entry->id == TypeTableEntryIdFn) { | 3762 | if (invoke_type_entry->id == TypeTableEntryIdFn) { |
| 3764 | return invoke_type_entry->data.fn.src_return_type; | 3763 | return analyze_fn_call_ptr(g, import, context, expected_type, node, invoke_type_entry, nullptr); |
| 3765 | } else { | 3764 | } else { |
| 3766 | add_node_error(g, fn_ref_expr, | 3765 | add_node_error(g, fn_ref_expr, |
| 3767 | buf_sprintf("type '%s' not a function", buf_ptr(&invoke_type_entry->name))); | 3766 | buf_sprintf("type '%s' not a function", buf_ptr(&invoke_type_entry->name))); |