From 1db70d46c62c9478ea84ccff204fb315136e518c Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 18 Dec 2024 15:21:20 -0500 Subject: Fix cross promotion between types with/without defaults --- compile.c | 4 ++++ types.c | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/compile.c b/compile.c index 38d25e1f..770b0191 100644 --- a/compile.c +++ b/compile.c @@ -126,6 +126,10 @@ static bool promote(env_t *env, ast_t *ast, CORD *code, type_t *actual, type_t * if (actual->tag == PointerType && needed->tag == PointerType) return true; + // Cross-promotion between tables with default values and without + if (needed->tag == TableType && actual->tag == TableType) + return true; + if (needed->tag == ClosureType && actual->tag == FunctionType) { *code = CORD_all("((Closure_t){", *code, ", NULL})"); return true; diff --git a/types.c b/types.c index 49505ae1..ce5f9df0 100644 --- a/types.c +++ b/types.c @@ -374,7 +374,9 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) if (needed->tag == PointerType && actual->tag == PointerType) { auto needed_ptr = Match(needed, PointerType); auto actual_ptr = Match(actual, PointerType); - if (needed_ptr->pointed->tag != MemoryType && !type_eq(needed_ptr->pointed, actual_ptr->pointed)) + if (needed_ptr->pointed->tag == TableType && actual_ptr->pointed->tag == TableType) + return can_promote(actual_ptr->pointed, needed_ptr->pointed); + else if (needed_ptr->pointed->tag != MemoryType && !type_eq(needed_ptr->pointed, actual_ptr->pointed)) // Can't use @Foo for a function that wants @Baz // But you *can* use @Foo for a function that wants @Memory return false; @@ -385,6 +387,15 @@ PUREFUNC bool can_promote(type_t *actual, type_t *needed) return true; } + // Cross-promotion between tables with default values and without + if (needed->tag == TableType && actual->tag == TableType) { + auto actual_table = Match(actual, TableType); + auto needed_table = Match(needed, TableType); + if (type_eq(needed_table->key_type, actual_table->key_type) + && type_eq(needed_table->value_type, actual_table->value_type)) + return true; + } + if (needed->tag == ClosureType && actual->tag == FunctionType) return can_promote(actual, Match(needed, ClosureType)->fn); -- cgit v1.2.3