commit 658dded6ba43f7ada9facda345742e4039fa12ec
parent 39599274468de63e4e8ee484e616fb8c695d5f11
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 31 Jan 2021 10:29:21 -0500
types: refactor tagged union castability rules
Diffstat:
M | src/types.c | | | 41 | +++++++---------------------------------- |
1 file changed, 7 insertions(+), 34 deletions(-)
diff --git a/src/types.c b/src/types.c
@@ -508,55 +508,28 @@ type_is_assignable(const struct type *to, const struct type *from)
}
static bool
-castable_to_tagged(const struct type *to, const struct type *from)
-{
- if (type_dealias(from)->storage == TYPE_STORAGE_TAGGED) {
- return true;
- }
-
- size_t ncastable = 0;
- to = type_dealias(to);
- for (const struct type_tagged_union *tu = &to->tagged;
- tu; tu = tu->next) {
- if (tu->type->id == from->id) {
- return true;
- }
- if (type_is_castable(tu->type, from)) {
- ++ncastable;
- }
- }
-
- return ncastable == 1;
-}
-
-static bool
castable_from_tagged(const struct type *to, const struct type *from)
{
- if (type_dealias(to)->storage == TYPE_STORAGE_TAGGED) {
- return true;
- }
-
- size_t ncastable = 0;
+ // TODO: This may need to be expanded upon
from = type_dealias(from);
for (const struct type_tagged_union *tu = &from->tagged;
tu; tu = tu->next) {
if (tu->type->id == to->id) {
return true;
}
- if (type_is_castable(tu->type, to)) {
- ++ncastable;
- }
}
-
- return ncastable == 1;
+ return false;
}
bool
type_is_castable(const struct type *to, const struct type *from)
{
if (type_dealias(to)->storage == TYPE_STORAGE_TAGGED) {
- return castable_to_tagged(to, from);
- } else if (type_dealias(from)->storage == TYPE_STORAGE_TAGGED) {
+ return tagged_select_subtype(to, from) != NULL
+ || tagged_subset_compat(to, from);
+ }
+
+ if (type_dealias(from)->storage == TYPE_STORAGE_TAGGED) {
return castable_from_tagged(to, from);
}