aboutsummaryrefslogtreecommitdiff
path: root/types.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-12-18 15:21:20 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-12-18 15:21:20 -0500
commit1db70d46c62c9478ea84ccff204fb315136e518c (patch)
tree0d0699614814d4a5064642c48d54c7382e8a9a8d /types.c
parent1df02db239aad3d19d142cacd04113f9934e947c (diff)
Fix cross promotion between types with/without defaults
Diffstat (limited to 'types.c')
-rw-r--r--types.c13
1 files changed, 12 insertions, 1 deletions
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);