made '<<' work for heaps; better overload robustness
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 16 Dec 2021 03:53:43 +0000 (21:53 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 16 Dec 2021 03:53:43 +0000 (21:53 -0600)
include/astnodes.h
src/checker.c
src/polymorph.h
src/types.c
tests/aoc-2021/day15.onyx

index b43811b0379855c98b3bc1b2c44f9dde086e8529..04c18923476bb781d74958221043d8e7bcd8b947 100644 (file)
@@ -1645,7 +1645,7 @@ void report_unable_to_match_overload(AstCall* call);
 void expand_macro(AstCall** pcall, AstFunction* template);
 AstFunction* macro_resolve_header(AstMacro* macro, Arguments* args, OnyxToken* callsite, b32 error_if_failed);
 
-Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos);
+Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos, b32 error_if_failed);
 
 // NOTE: Useful inlined functions
 static inline b32 is_lval(AstNode* node) {
index 36f6f9a273dc084c17b9367edab004ced6b52f6e..73c3fe3d946ecc4736472ee73d407cd32e6bb465 100644 (file)
@@ -2032,7 +2032,7 @@ CheckStatus check_struct(AstStructType* s_node) {
         YIELD(s_node->token->pos, "Waiting for struct member defaults to pass symbol resolution.");
 
     if (s_node->constraints.constraints) {
-        s_node->constraints.produce_errors = 1;
+        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);
     }
 
@@ -2179,14 +2179,15 @@ CheckStatus check_function_header(AstFunction* func) {
             expect_default_param = 1;
         }
 
-        if (local->type_node != NULL) CHECK(type, local->type_node);
+        if (local->type_node != NULL) {
+            // If the function has the no_error flag, then the type node should have it set too.
+            // This allows for polymorphic structures with constraints to fail gracefully.
+            local->type_node->flags |= (func->flags & Ast_Flag_Header_Check_No_Error);
+            CHECK(type, local->type_node);
+        }
 
         fill_in_type((AstTyped *) local);
         if (local->type == NULL) {
-            // onyx_report_error(param->local->token->pos,
-            //         "Unable to resolve type for parameter, '%b'",
-            //         local->token->text,
-            //         local->token->length);
             YIELD(local->token->pos, "Waiting for parameter type to be known.");
         }
 
@@ -2613,9 +2614,14 @@ CheckStatus check_constraint_context(ConstraintContext *cc, Scope *scope, OnyxFi
 
                     onyx_report_error(constraint->exprs[constraint->expr_idx]->token->pos, "Failed to satisfy constraint where %s.", constraint_map);
                     onyx_report_error(constraint->token->pos, "Here is where the interface was used.");
-                }
 
-                return Check_Error;
+                    return Check_Error;
+
+                } else {
+                    // If no error are suppose to be produced, we still need to signal that 
+                    // the node reached a completed state.
+                    return Check_Failed;
+                }
             }
 
             if (cc->constraint_checks[i] == Constraint_Check_Status_Queued) {
index 23c8cc2464a1d3b1b40f262a7d44c0a89ab84bf8..b1b5c6c3dc75ea2b0b4f63e22a5579da9a16998c 100644 (file)
@@ -890,7 +890,7 @@ char* build_poly_struct_name(AstPolyStructType* ps_type, Type* cs_type) {
     return bh_aprintf(global_heap_allocator, "%s", name_buf);
 }
 
-Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos) {
+Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos, b32 error_if_failed) {
     // @Cleanup
     assert(ps_type->scope != NULL);
 
@@ -910,7 +910,7 @@ Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySoluti
     i32 i = 0;
     bh_arr_each(AstPolySolution, sln, slns) {
         sln->poly_sym = (AstNode *) &ps_type->poly_params[i];
-        
+
         PolySolutionKind expected_kind = PSK_Undefined;
         if ((AstNode *) ps_type->poly_params[i].type_node == (AstNode *) &basic_type_type_expr) {
             expected_kind = PSK_Type;
@@ -974,6 +974,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);
+    BH_MASK_SET(concrete_struct->flags, !error_if_failed, Ast_Flag_Header_Check_No_Error);
     shput(ps_type->concrete_structs, unique_key, concrete_struct);
 
     add_entities_for_node(NULL, (AstNode *) concrete_struct, sln_scope, NULL);
index 3cf40a3cff68c90710cc473935c1c6f1adbca037..ca2bb4d5dad4fb9d728b75c62b205a21ef39e39d 100644 (file)
@@ -589,7 +589,7 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) {
                 }
             }
 
-            Type* concrete = polymorphic_struct_lookup(ps_type, slns, pc_type->token->pos);
+            Type* concrete = polymorphic_struct_lookup(ps_type, slns, pc_type->token->pos, (pc_type->flags & Ast_Flag_Header_Check_No_Error) == 0);
 
             // This should be copied in the previous function.
             // CLEANUP: Maybe don't copy it and just use this one since it is allocated on the heap?
index a9a869a3ddf8a97ebbae30e579968a55b3936e6e..7b1e641d796096a5e140448d9bbb5d6dbdf18caa 100644 (file)
@@ -28,7 +28,7 @@ main :: (args) => {
         to_try := heap.make(queued, (x, y) => x.cost - y.cost);
         tried := set.make(pos);
 
-        heap.insert(^to_try, .{ 0, 0, -cast(i32) (cells[0] - #char "0") });
+        to_try << .{ 0, 0, -cast(i32) (cells[0] - #char "0") };
 
         minimum := 0;
         while to_try.data.count != 0 {
@@ -50,7 +50,7 @@ main :: (args) => {
                         if found := array.find_ptr(to_try.data, .{try.x + dx, try.y + dy, 0}); found != null {
                             found.cost = math.min(cell_value, found.cost);
                         } else {
-                            heap.insert(^to_try, .{try.x + dx, try.y + dy, cell_value });
+                            to_try << .{try.x + dx, try.y + dy, cell_value };
                         }
                     }
                 }