AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual);
AstTyped* find_matching_overload_by_arguments(bh_arr(AstTyped *) overloads, Arguments* args);
+AstTyped* find_matching_overload_by_type(bh_arr(AstTyped *) overloads, Type* type);
void report_unable_to_match_overload(AstCall* call);
AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos);
return 1;
}
+ if (node->kind == Ast_Kind_Overloaded_Function) {
+ AstTyped* func = find_matching_overload_by_type(((AstOverloadedFunction *) node)->overloads, type);
+ if (func == NULL) return 0;
+
+ // HACK: It feels like there should be a better place to flag that a procedure was definitely used.
+ if (func->kind == Ast_Kind_Function)
+ func->flags |= Ast_Flag_Function_Used;
+
+ *pnode = func;
+ node = *pnode;
+ }
+
if (node->kind == Ast_Kind_Polymorphic_Proc) {
AstFunction* func = polymorphic_proc_lookup((AstPolyProc *) node, PPLM_By_Function_Type, type, node->token);
if (func == NULL) return 0;
}
char* get_function_name(AstFunction* func) {
+ if (func->kind != Ast_Kind_Function) return "<procedure>";
+
if (func->name != NULL) {
return bh_aprintf(global_scratch_allocator, "%b", func->name->text, func->name->length);
}
CHECK(expression, &(*parg)->value);
(*parg)->type = (*parg)->value->type;
- if ((*parg)->value->kind == Ast_Kind_Overloaded_Function) {
- onyx_report_error((*parg)->token->pos,
- "Cannot pass overloaded function '%b' as argument.",
- (*parg)->value->token->text, (*parg)->value->token->length);
- return Check_Error;
- }
-
return Check_Success;
}
if (consume_token_if_next(parser, '{')) {
AstOverloadedFunction* ofunc = make_node(AstOverloadedFunction, Ast_Kind_Overloaded_Function);
ofunc->token = token;
+ ofunc->flags |= Ast_Flag_Comptime;
bh_arr_new(global_heap_allocator, ofunc->overloads, 4);
return matched_overload;
}
+AstTyped* find_matching_overload_by_type(bh_arr(AstTyped *) overloads, Type* type) {
+ if (type->kind != Type_Kind_Function) return NULL;
+
+ bh_imap all_overloads;
+ bh_imap_init(&all_overloads, global_heap_allocator, bh_arr_length(overloads) * 2);
+ build_all_overload_options(overloads, &all_overloads);
+
+ AstTyped *matched_overload = NULL;
+
+ bh_arr_each(bh__imap_entry, entry, all_overloads.entries) {
+ AstTyped* node = (AstTyped *) entry->key;
+ if (node->kind == Ast_Kind_Overloaded_Function) continue;
+
+ if (type_check_or_auto_cast(&node, type)) {
+ matched_overload = node;
+ break;
+ }
+ }
+
+ bh_imap_free(&all_overloads);
+ return matched_overload;
+}
+
void report_unable_to_match_overload(AstCall* call) {
char* arg_str = bh_alloc(global_scratch_allocator, 1024);
arg_str[0] = '\0';