From: Brendan Hansen Date: Thu, 7 Dec 2023 00:35:28 +0000 (-0600) Subject: added: better error message when `->` is used incorrectly X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=39a7ce493845f8060fa3f3f23a8d057096058811;p=onyx.git added: better error message when `->` is used incorrectly --- diff --git a/compiler/include/astnodes.h b/compiler/include/astnodes.h index 84a112ef..73c51380 100644 --- a/compiler/include/astnodes.h +++ b/compiler/include/astnodes.h @@ -696,6 +696,7 @@ struct AstArgument { VarArgKind va_kind; b32 is_baked : 1; b32 pass_as_any : 1; + b32 used_as_lval_of_method_call : 1; }; struct AstSubscript { AstTyped_base; diff --git a/compiler/src/checker.c b/compiler/src/checker.c index bdf8277f..f09f8e9a 100644 --- a/compiler/src/checker.c +++ b/compiler/src/checker.c @@ -2249,10 +2249,11 @@ CheckStatus check_method_call(AstBinaryOp** pmcall) { implicit_argument = (AstTyped *) address_of; } - implicit_argument = (AstTyped *) make_argument(context.ast_alloc, implicit_argument); + AstArgument *new_arg = make_argument(context.ast_alloc, implicit_argument); + new_arg->used_as_lval_of_method_call = 1; bh_arr_insertn(call_node->args.values, 0, 1); - call_node->args.values[0] = implicit_argument; + call_node->args.values[0] = (AstTyped *) new_arg; mcall->right->next = mcall->next; mcall->flags |= Ast_Flag_Has_Been_Checked; diff --git a/compiler/src/utils.c b/compiler/src/utils.c index 1262c01f..dab01847 100644 --- a/compiler/src/utils.c +++ b/compiler/src/utils.c @@ -1113,6 +1113,21 @@ TypeMatch check_arguments_against_type(Arguments* args, TypeFunction* func_type, if (tm == TYPE_MATCH_SPECIAL) return tm; if (tm == TYPE_MATCH_FAILED) { if (error != NULL) { + AstArgument *the_arg = (void *) arg_arr[arg_pos]; + if (the_arg->used_as_lval_of_method_call) { + if (formal_params[arg_pos]->kind == Type_Kind_Pointer && + formal_params[arg_pos]->Pointer.elem == arg_arr[arg_pos]->type) { + // We didn't match the type, and this arg was from a method call, + // and its because it wanted a &T, but got a T. This is likely + // due to the fact that the method call argument is not an lval. + error->pos = arg_arr[arg_pos]->token->pos; + error->text = bh_aprintf(global_heap_allocator, + "This method expects a pointer to the first argument, which normally `->` would do automatically, but in this case, the left-hand side is not an l-value, so its address cannot be taken. Try storing it in a temporary variable first, then calling the method." + ); + return tm; + } + } + error->pos = arg_arr[arg_pos]->token->pos; error->text = bh_aprintf(global_heap_allocator, "The procedure '%s' expects a value of type '%s' for %d%s parameter, got '%s'.",