better error messages when using constraints and polymorphism
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 3 Jan 2022 03:42:22 +0000 (21:42 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 3 Jan 2022 03:42:22 +0000 (21:42 -0600)
include/astnodes.h
src/checker.c
src/polymorph.h

index 2bdbe97599b0a232763a30a2806abaf10d670e35..3b352d6d880eb87cf9b8efeee2d552295f7bc21d 100644 (file)
@@ -883,6 +883,7 @@ struct AstStructType {
     struct Entity* entity_type;
     struct Entity* entity_defaults;
 
+    OnyxFilePos polymorphic_error_loc;
     ConstraintContext constraints;
 
     b32 stcache_is_valid : 1;
index b9edd1a0e4dd18cbf08314f31272364d889a85a9..22bc73fce7cf16406b148d5c1329f4c372496fae 100644 (file)
@@ -2041,7 +2041,12 @@ CheckStatus check_struct(AstStructType* s_node) {
 
     if (s_node->constraints.constraints) {
         s_node->constraints.produce_errors = (s_node->flags & Ast_Flag_Header_Check_No_Error) == 0;
-        CHECK(constraint_context, &s_node->constraints, s_node->scope, s_node->token->pos);
+
+        OnyxFilePos pos = s_node->token->pos;
+        if (s_node->polymorphic_error_loc.filename) {
+            pos = s_node->polymorphic_error_loc;
+        }
+        CHECK(constraint_context, &s_node->constraints, s_node->scope, pos);
     }
 
     bh_arr_each(AstStructMember *, smem, s_node->members) {
@@ -2631,6 +2636,7 @@ CheckStatus check_constraint_context(ConstraintContext *cc, Scope *scope, OnyxFi
 
                     onyx_report_error(constraint->exprs[constraint->expr_idx]->token->pos, Error_Critical, "Failed to satisfy constraint where %s.", constraint_map);
                     onyx_report_error(constraint->token->pos, Error_Critical, "Here is where the interface was used.");
+                    onyx_report_error(pos, Error_Critical, "Here is the code that caused this constraint to be checked.");
 
                     return Check_Error;
 
index a5a4db397ea753da27d85e97db11b1fa536f7088..0dfcfee16c5cbe0c4ee531333a782e0cd1c0491b 100644 (file)
@@ -500,7 +500,16 @@ static void solve_for_polymorphic_param_type(PolySolveResult* resolved, AstFunct
         default: return;
     }
 
-    *resolved = solve_poly_type(param->poly_sym, param->type_expr, actual_type);
+    PolySolveResult res = solve_poly_type(param->poly_sym, param->type_expr, actual_type);
+    if (res.kind == PSK_Undefined) {
+        *err_msg = bh_aprintf(global_scratch_allocator,
+            "Unable to solve for polymorphic variable '%b', given the type '%s'.",
+            param->poly_sym->token->text,
+            param->poly_sym->token->length,
+            type_get_name(actual_type));
+    }
+
+    *resolved = res;
 }
 
 
@@ -979,6 +988,7 @@ Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySoluti
     insert_poly_slns_into_scope(sln_scope, slns);
 
     AstStructType* concrete_struct = (AstStructType *) ast_clone(context.ast_alloc, ps_type->base_struct);
+    concrete_struct->polymorphic_error_loc = pos;
     BH_MASK_SET(concrete_struct->flags, !error_if_failed, Ast_Flag_Header_Check_No_Error);
     shput(ps_type->concrete_structs, unique_key, concrete_struct);