diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f2cdcc2ea..14967482f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7255,18 +7255,45 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, } } + // auto print_argument_types = [&]() { + // error_line("\tGiven argument types: ("); + // isize i = 0; + // for (Operand const &o : positional_operands) { + // if (i++ > 0) error_line(", "); + // gbString type = type_to_string(o.type); + // defer (gb_string_free(type)); + // error_line("%s", type); + // } + // for (Operand const &o : named_operands) { + // if (i++ > 0) error_line(", "); + + // gbString type = type_to_string(o.type); + // defer (gb_string_free(type)); + + // if (i < ce->split_args->named.count) { + // Ast *named_field = ce->split_args->named[i]; + // ast_node(fv, FieldValue, named_field); + + // gbString field = expr_to_string(fv->field); + // defer (gb_string_free(field)); + + // error_line("%s = %s", field, type); + // } else { + // error_line("%s", type); + // } + // } + // error_line(")\n"); + // }; + auto print_argument_types = [&]() { - error_line("\tGiven argument types: ("); + error_line("\tGiven argument types:\n"); isize i = 0; for (Operand const &o : positional_operands) { - if (i++ > 0) error_line(", "); gbString type = type_to_string(o.type); defer (gb_string_free(type)); - error_line("%s", type); + error_line("\t • %s\n", type); } for (Operand const &o : named_operands) { - if (i++ > 0) error_line(", "); - gbString type = type_to_string(o.type); defer (gb_string_free(type)); @@ -7277,12 +7304,11 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, gbString field = expr_to_string(fv->field); defer (gb_string_free(field)); - error_line("%s = %s", field, type); + error_line("\t • %s = %s\n", field, type); } else { - error_line("%s", type); + error_line("\t • %s\n", type); } } - error_line(")\n"); }; if (valids.count == 0) { @@ -7298,9 +7324,6 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, if (procs.count == 0) { procs = proc_group_entities_cloned(c, *operand); } - if (procs.count > 0) { - error_line("Did you mean to use one of the following:\n"); - } // Try to reduce the list further for `$T: typeid` like parameters bool *possibly_ignore = temporary_alloc_array(procs.count); @@ -7397,6 +7420,80 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, } spaces[max_spaces] = 0; + { + bool try_addr = false; + isize try_addr_idx = -1; + + for_array(i, procs) { + if (possibly_ignore_set != 0 && possibly_ignore[i]) { + continue; + } + Entity *proc = procs[i]; + TokenPos pos = proc->token.pos; + Type *t = base_type(proc->type); + if (t == t_invalid) continue; + GB_ASSERT(t->kind == Type_Proc); + if (t->Proc.params && t->Proc.params->Tuple.variables.count > 0) { + isize n = gb_min(t->Proc.params->Tuple.variables.count, positional_operands.count); + for (isize i = 0; i < n; i++) { + Type *dst = t->Proc.params->Tuple.variables[i]->type; + Operand src = positional_operands[i]; + if (check_is_assignable_to(c, &src, dst)) { + // okay + } else if (check_is_assignable_to(c, &src, type_deref(dst))) { + try_addr = true; + if (try_addr_idx < 0) { + try_addr_idx = i; + } + } + } + } + } + + if (try_addr) { + error_line(" \n"); + error_line("\tSuggestion:\n"); + error_line("\t\t%s(", expr_name); + isize i = 0; + for (Operand const &o : positional_operands) { + if (i++ > 0) error_line(", "); + gbString expr = expr_to_string(o.expr); + defer (gb_string_free(expr)); + + if (i-1 == try_addr_idx) { + error_line("&"); + } + error_line("%s", expr); + } + for (Operand const &o : named_operands) { + if (i++ > 0) error_line(", "); + + gbString expr = expr_to_string(o.expr); + defer (gb_string_free(expr)); + + if (i < ce->split_args->named.count) { + Ast *named_field = ce->split_args->named[i]; + ast_node(fv, FieldValue, named_field); + + gbString field = expr_to_string(fv->field); + defer (gb_string_free(field)); + + error_line("%s = %s", field, expr); + } else { + error_line("%s", expr); + } + } + error_line(")\n"); + + error_line(" \n"); // extra spaces to prevent newlines being consumed by the error handling syste, + } + } + + + if (procs.count > 0) { + error_line("Did you mean one of the following overloads?\n"); + } + for_array(i, procs) { if (possibly_ignore_set != 0 && possibly_ignore[i]) { continue;