bug fixes with constriant checking on polymorphic procedures
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 29 Nov 2021 19:16:15 +0000 (13:16 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 29 Nov 2021 19:16:15 +0000 (13:16 -0600)
include/astnodes.h
src/astnodes.c
src/checker.c
src/symres.c
src/utils.c
tests/interfaces
tests/interfaces.onyx

index d0ad9662236d315edfb9219c43d014adeb1fe32c..e1f82cc7623beb1b7bef9de9be48f50bd1a08203 100644 (file)
@@ -1565,6 +1565,7 @@ void arguments_copy(Arguments* dest, Arguments* src);
 void arguments_clone(Arguments* dest, Arguments* src);
 void arguments_deep_clone(bh_allocator a, Arguments* dest, Arguments* src);
 void arguments_remove_baked(Arguments* args);
+void arguments_clear_baked_flags(Arguments* args);
 TypeMatch check_arguments_against_type(Arguments* args, TypeFunction* func_type, VarArgKind* va_kind,
                                  OnyxToken* location, char* func_name, struct OnyxError* error);
 i32 get_argument_buffer_size(TypeFunction* type, Arguments* args);
index 8990c47f398b6636fd7585ec1ef4fece90830841..5ec5420eac25fef687e57ff9847e72a404a3d222 100644 (file)
@@ -1194,6 +1194,20 @@ void arguments_remove_baked(Arguments* args) {
     }
 }
 
+void arguments_clear_baked_flags(Arguments* args) {
+    bh_arr_each(AstTyped *, arg, args->values) {
+        if ((*arg)->kind == Ast_Kind_Argument) {
+            ((AstArgument *) *arg)->is_baked = 0;
+        }
+    }
+
+    bh_arr_each(AstNamedValue *, arg, args->named_values) {
+        if ((*arg)->value->kind == Ast_Kind_Argument) {
+            ((AstArgument *) (*arg)->value)->is_baked = 0;
+        }
+    }
+}
+
 // GROSS: Using void* to avoid having to cast everything.
 const char* node_get_type_name(void* node) {
     if (node_is_type((AstNode *) node)) return "type_expr";
index 6d9c94cdf3fd3a1cc0023e6e4ddaf2f9b54aa4f6..fecad0160d9dfa47c1b207c9dca22fa15d0ba573 100644 (file)
@@ -96,7 +96,7 @@ CheckStatus check_type(AstType* type);
 CheckStatus check_insert_directive(AstDirectiveInsert** pinsert);
 CheckStatus check_do_block(AstDoBlock** pdoblock);
 CheckStatus check_constraint(AstConstraint *constraint);
-CheckStatus check_constraint_context(ConstraintContext *cc, OnyxFilePos pos);
+CheckStatus check_constraint_context(ConstraintContext *cc, Scope *scope, OnyxFilePos pos);
 CheckStatus check_polyquery(AstPolyQuery *query);
 
 // HACK HACK HACK
@@ -1988,7 +1988,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) {
-        CHECK(constraint_context, &s_node->constraints, s_node->token->pos);
+        CHECK(constraint_context, &s_node->constraints, s_node->scope, s_node->token->pos);
     }
 
     bh_arr_each(AstStructMember *, smem, s_node->members) {
@@ -2173,7 +2173,7 @@ CheckStatus check_function_header(AstFunction* func) {
     if (func->return_type != NULL) CHECK(type, func->return_type);
 
     if (func->constraints.constraints != NULL) {
-        CHECK(constraint_context, &func->constraints, func->token->pos);
+        CHECK(constraint_context, &func->constraints, func->scope, func->token->pos);
     }
 
     func->type = type_build_function_type(context.ast_alloc, func);
@@ -2465,6 +2465,10 @@ CheckStatus check_macro(AstMacro* macro) {
 CheckStatus check_constraint(AstConstraint *constraint) {
     switch (constraint->phase) {
         case Constraint_Phase_Cloning_Expressions: {
+            if (constraint->interface->kind == Ast_Kind_Symbol) {
+                return Check_Return_To_Symres;
+            }
+
             if (constraint->interface->kind != Ast_Kind_Interface) {
                 // CLEANUP: This error message might not look totally right in some cases.
                 ERROR_(constraint->token->pos, "'%b' is not an interface. It is a '%s'.",
@@ -2524,7 +2528,7 @@ CheckStatus check_constraint(AstConstraint *constraint) {
     return Check_Success;
 }
 
-CheckStatus check_constraint_context(ConstraintContext *cc, OnyxFilePos pos) {
+CheckStatus check_constraint_context(ConstraintContext *cc, Scope *scope, OnyxFilePos pos) {
     if (cc->constraint_checks) {
         if (cc->constraints_met == 1) return Check_Success;
 
@@ -2569,7 +2573,7 @@ CheckStatus check_constraint_context(ConstraintContext *cc, OnyxFilePos pos) {
             cc->constraints[i]->report_status = &ccs[i];
             cc->constraints[i]->phase = Constraint_Phase_Cloning_Expressions;
 
-            add_entities_for_node(NULL, (AstNode *) cc->constraints[i], NULL, NULL);
+            add_entities_for_node(NULL, (AstNode *) cc->constraints[i], scope, NULL);
         }
 
         return Check_Yield_Macro;
index 55f22e35f4c38e20476b6c5e8a5e8f1612c51084..c6345789d50f06f980668cee6514e4ae2419439a 100644 (file)
@@ -1288,6 +1288,7 @@ static SymresStatus symres_macro(AstMacro* macro) {
 
 static SymresStatus symres_constraint(AstConstraint* constraint) {
     switch (constraint->phase) {
+        case Constraint_Phase_Cloning_Expressions:
         case Constraint_Phase_Waiting_To_Be_Queued: {
             SYMRES(expression, (AstTyped **) &constraint->interface);
 
index fad581fd359e244704bee0cd12417016291a6386..900acf2dd6af7d8518352138b31e18e0c5d36986 100644 (file)
@@ -363,9 +363,12 @@ AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads,
 
         AstFunction* overload = NULL;
         switch (node->kind) {
-            case Ast_Kind_Function:         overload = (AstFunction *) node; break;
             case Ast_Kind_Macro:            overload = macro_resolve_header((AstMacro *) node, param_args, NULL, 0); break;
             case Ast_Kind_Polymorphic_Proc: overload = polymorphic_proc_build_only_header((AstPolyProc *) node, PPLM_By_Arguments, param_args); break;
+            case Ast_Kind_Function:
+                overload = (AstFunction *) node;
+                arguments_clear_baked_flags(&args);
+                break;
         }
 
         // NOTE: Overload is not something that is known to be overloadable.
index 4526d7c7d63f79868cc904a3a05631d6f4af2a91..af3069feda358b95ed8fc79be42da55b6e02397f 100644 (file)
@@ -8,3 +8,6 @@ Allocator is not hashable!
 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
 true
 false
+true
+false
+true
index 9ba92e06aa3976102c9c9746dd93c71bbe3b1e05..f07fe6cdda50122755fdc848047207edd36b05dc 100644 (file)
@@ -23,10 +23,10 @@ CanCastTo :: interface (T: type_expr, D: type_expr) {
 // I don't know why this doesn't work... It is complaining that it couldn't match
 // either of these cases, but if I remove the first, it matches the second. This
 // is clearly wrong behavior, but I don't immediately see where the problem is.
-// cast_able :: #match {
-//     (_: $T, $D: type_expr) -> bool where CanCastTo(T, D) do return true; ,
-//     (_: any, d: type_expr) -> bool { return false; },
-// }
+cast_able :: #match {
+    (_: $T, $D: type_expr) -> bool where CanCastTo(T, D) do return true; ,
+    (_: any, d: type_expr) -> bool { return false; },
+}
 
 cast_able_to_int :: #match {
     macro (_: $T)  -> bool where CanCastTo(T, i32) { return true; },
@@ -108,4 +108,10 @@ main :: (args: [] cstr) {
 
     println(cast_able_to_int(12.34));
     println(cast_able_to_int("test"));
+
+    println(cast_able(12.34, i32));
+    println(cast_able("foo", i32));
+
+    b: [10] i32;
+    println(cast_able(b, [] i32));
 }