better error reporting for polymorphic procedures
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 16 Jan 2021 17:15:08 +0000 (11:15 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 16 Jan 2021 17:15:08 +0000 (11:15 -0600)
include/onyxastnodes.h
onyx.exe
src/onyxastnodes.c
src/onyxchecker.c
src/onyxsymres.c
src/onyxutils.c

index 7fe4c937df26c04e122449dd0544beac6cbd1951..dd93a7f7fd270bb2fa66e62e811076a2cd3f26ae 100644 (file)
@@ -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);
 
 
index 018363e400c939ca96ad12d8a0e3164173a0e48f..c405dd6fd0d0dc5741b099274e0a19e84d9ae724 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index ba52da93413f82fe56e5726e0a34f60eebb91d78..b2a2eb6e5072228389037008d93418d5d073d691 100644 (file)
@@ -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;
index 25459e0fb6d06ad0c739295b3cc7ebe53a18b1fb..b6f90a593309712488efd74d3521b3b578e969e8 100644 (file)
@@ -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;
 }
index fd30f2a49fe0bba43688c92c3acbd9de27f5c8f6..1bdd3df6ccbd0da006257515099db2e17e975963 100644 (file)
@@ -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;
index f5c4e2527c78b6c06e6bdb5365b8fed620721991..eec1472ce54ed4b7a65a4bf1d64a069df0901cfc 100644 (file)
@@ -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