From: Brendan Hansen Date: Sat, 16 Jan 2021 17:15:08 +0000 (-0600) Subject: better error reporting for polymorphic procedures X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=e49ef324dd2171c471d4a31efdb4560f9360d9a5;p=onyx.git better error reporting for polymorphic procedures --- diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 7fe4c937..dd93a7f7 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -1009,9 +1009,9 @@ typedef enum PolyProcLookupMethod { PPLM_By_Function_Type, PPLM_By_Arguments, } PolyProcLookupMethod; -AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxFilePos pos); -AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxFilePos pos); -AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxFilePos pos); +AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxToken* tkn); +AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxToken* tkn); +AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxToken* tkn); AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual); diff --git a/onyx.exe b/onyx.exe index 018363e4..c405dd6f 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index ba52da93..b2a2eb6e 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -415,7 +415,7 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) { assert(node != NULL); if (node->kind == Ast_Kind_Polymorphic_Proc) { - AstFunction* func = polymorphic_proc_lookup((AstPolyProc *) node, PPLM_By_Function_Type, type, node->token->pos); + AstFunction* func = polymorphic_proc_lookup((AstPolyProc *) node, PPLM_By_Function_Type, type, node->token); if (func == NULL) return 0; *pnode = (AstTyped *) func; diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 25459e0f..b6f90a59 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -450,11 +450,7 @@ CheckStatus check_call(AstCall* call) { } if (callee->kind == Ast_Kind_Polymorphic_Proc) { - call->callee = (AstTyped *) polymorphic_proc_lookup( - (AstPolyProc *) call->callee, - PPLM_By_Call, - call, - call->token->pos); + call->callee = (AstTyped *) polymorphic_proc_lookup((AstPolyProc *) call->callee, PPLM_By_Call, call, call->token); if (call->callee == NULL) return Check_Error; @@ -1126,13 +1122,17 @@ CheckStatus check_range_literal(AstRangeLiteral** prange) { type_lookup_member(expected_range_type, "low", &smem); if (!type_check_or_auto_cast(&range->low, smem.type)) { - onyx_report_error(range->token->pos, "Expected left side of range to be a 32-bit integer."); + onyx_report_error(range->token->pos, + "Expected left side of range to be a 32-bit integer, got '%s'.", + type_get_name(range->low->type)); return Check_Error; } type_lookup_member(expected_range_type, "high", &smem); if (!type_check_or_auto_cast(&range->high, smem.type)) { - onyx_report_error(range->token->pos, "Expected right side of range to be a 32-bit integer."); + onyx_report_error(range->token->pos, + "Expected right side of range to be a 32-bit integer, got '%s'.", + type_get_name(range->high->type)); return Check_Error; } @@ -1522,7 +1522,13 @@ CheckStatus check_block(AstBlock* block) { CheckStatus check_function(AstFunction* func) { semstate.expected_return_type = func->type->Function.return_type; - if (func->body) return check_block(func->body); + if (func->body) { + CheckStatus status = check_block(func->body); + if (status != Check_Success && func->generated_from) + onyx_report_error(func->generated_from->pos, "Error in polymorphic procedure generated from this location."); + + return status; + } return Check_Success; } diff --git a/src/onyxsymres.c b/src/onyxsymres.c index fd30f2a4..1bdd3df6 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -565,7 +565,7 @@ static void symres_directive_solidify(AstDirectiveSolidify** psolid) { if (onyx_has_errors()) return; } - solid->resolved_proc = polymorphic_proc_try_solidify(solid->poly_proc, solid->known_polyvars, solid->token->pos); + solid->resolved_proc = polymorphic_proc_try_solidify(solid->poly_proc, solid->known_polyvars, solid->token); // NOTE: Not a DirectiveSolidify. *psolid = (AstDirectiveSolidify *) solid->resolved_proc; diff --git a/src/onyxutils.c b/src/onyxutils.c index f5c4e252..eec1472c 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -167,6 +167,7 @@ static void insert_poly_slns_into_scope(Scope* scope, bh_arr(AstPolySolution) sl case PSK_Value: // CLEANUP: Maybe clone this? + assert(sln->value->flags & Ast_Flag_Comptime); node = (AstNode *) sln->value; break; } @@ -459,17 +460,17 @@ sln_not_found: return NULL; } -AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxFilePos pos) { +AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxToken* tkn) { ensure_polyproc_cache_is_created(pp); char *err_msg = NULL; bh_arr(AstPolySolution) slns = find_polymorphic_slns(pp, pp_lookup, actual, &err_msg); if (slns == NULL) { - if (err_msg != NULL) onyx_report_error(pos, err_msg); - else onyx_report_error(pos, "Some kind of error occured when generating a polymorphic procedure. You hopefully will not see this"); + if (err_msg != NULL) onyx_report_error(tkn->pos, err_msg); + else onyx_report_error(tkn->pos, "Some kind of error occured when generating a polymorphic procedure. You hopefully will not see this"); } - AstFunction* result = polymorphic_proc_solidify(pp, slns, pos); + AstFunction* result = polymorphic_proc_solidify(pp, slns, tkn); bh_arr_free(slns); return result; @@ -522,7 +523,7 @@ static char* build_poly_slns_unique_key(bh_arr(AstPolySolution) slns) { return key_buf; } -b32 add_solidified_function_entities(AstSolidifiedFunction solidified_func, b32 header_already_processed) { +static b32 add_solidified_function_entities(AstSolidifiedFunction solidified_func, b32 header_already_processed) { solidified_func.func->flags |= Ast_Flag_Function_Used; solidified_func.func->flags |= Ast_Flag_From_Polymorphism; @@ -554,7 +555,7 @@ b32 add_solidified_function_entities(AstSolidifiedFunction solidified_func, b32 return 1; } -AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxFilePos pos) { +AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxToken* tkn) { ensure_polyproc_cache_is_created(pp); // NOTE: Check if a version of this polyproc has already been created. @@ -566,7 +567,7 @@ AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) clone_function_body(semstate.node_allocator, solidified_func.func, pp->base_func); if (!add_solidified_function_entities(solidified_func, 1)) { - onyx_report_error(pos, "Error in polymorphic procedure header generated from this call site."); + onyx_report_error(tkn->pos, "Error in polymorphic procedure header generated from this call site."); return NULL; } @@ -577,22 +578,25 @@ AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) } AstSolidifiedFunction solidified_func; - solidified_func.poly_scope = scope_create(semstate.node_allocator, pp->poly_scope, pos); + solidified_func.poly_scope = scope_create(semstate.node_allocator, pp->poly_scope, tkn->pos); insert_poly_slns_into_scope(solidified_func.poly_scope, slns); solidified_func.func = (AstFunction *) ast_clone(semstate.node_allocator, pp->base_func); bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func); + solidified_func.func->generated_from = tkn; + if (!add_solidified_function_entities(solidified_func, 0)) { - onyx_report_error(pos, "Error in polymorphic procedure header generated from this call site."); + onyx_report_error(tkn->pos, "Error in polymorphic procedure header generated from this call site."); return NULL; } + return solidified_func.func; } // NOTE: This can return either a AstFunction or an AstPolyProc, depending if enough parameters were // supplied to remove all the polymorphic variables from the function. -AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxFilePos pos) { +AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxToken* tkn) { i32 valid_argument_count = 0; bh_arr_each(AstPolySolution, sln, slns) { @@ -608,7 +612,7 @@ AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) if (found_match) { valid_argument_count++; } else { - onyx_report_error(pos, "'%b' is not a type variable of '%b'.", + onyx_report_error(tkn->pos, "'%b' is not a type variable of '%b'.", sln->poly_sym->token->text, sln->poly_sym->token->length, pp->token->text, pp->token->length); return (AstNode *) pp; @@ -616,7 +620,7 @@ AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) } if (valid_argument_count == bh_arr_length(pp->poly_params)) { - return (AstNode *) polymorphic_proc_solidify(pp, slns, pos); + return (AstNode *) polymorphic_proc_solidify(pp, slns, tkn); } else { // HACK: Some of these initializations assume that the entity for this polyproc has