From: Brendan Hansen Date: Mon, 29 Nov 2021 19:16:15 +0000 (-0600) Subject: bug fixes with constriant checking on polymorphic procedures X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=9c242c607a2306bb8eb6ee3a217208fbc7e37a05;p=onyx.git bug fixes with constriant checking on polymorphic procedures --- diff --git a/include/astnodes.h b/include/astnodes.h index d0ad9662..e1f82cc7 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -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); diff --git a/src/astnodes.c b/src/astnodes.c index 8990c47f..5ec5420e 100644 --- a/src/astnodes.c +++ b/src/astnodes.c @@ -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"; diff --git a/src/checker.c b/src/checker.c index 6d9c94cd..fecad016 100644 --- a/src/checker.c +++ b/src/checker.c @@ -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; diff --git a/src/symres.c b/src/symres.c index 55f22e35..c6345789 100644 --- a/src/symres.c +++ b/src/symres.c @@ -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); diff --git a/src/utils.c b/src/utils.c index fad581fd..900acf2d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -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. diff --git a/tests/interfaces b/tests/interfaces index 4526d7c7..af3069fe 100644 --- a/tests/interfaces +++ b/tests/interfaces @@ -8,3 +8,6 @@ Allocator is not hashable! [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] true false +true +false +true diff --git a/tests/interfaces.onyx b/tests/interfaces.onyx index 9ba92e06..f07fe6cd 100644 --- a/tests/interfaces.onyx +++ b/tests/interfaces.onyx @@ -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)); }