aboutsummaryrefslogtreecommitdiff
path: root/src/typecheck.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-04 18:29:09 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-04 18:29:09 -0400
commit7b735ab6fc3e0bb368f1ca484168eaefbbe3ce9c (patch)
tree4a7c78bb0967b8fbc1042d901cf0346705d9d0d8 /src/typecheck.c
parent0b8074154e2671691050bdb3bcb33245625a056c (diff)
Misc fixes
Diffstat (limited to 'src/typecheck.c')
-rw-r--r--src/typecheck.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/typecheck.c b/src/typecheck.c
index cd6ff1c2..8d4cc946 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -1163,6 +1163,26 @@ type_t *get_type(env_t *env, ast_t *ast)
code_err(binop.rhs, "I only know how to do bit shifting by integer amounts, not ", type_to_str(rhs_t));
}
+ if (is_numeric_type(lhs_t) && binop.rhs->tag == Int) {
+ return lhs_t;
+ } else if (is_numeric_type(rhs_t) && binop.lhs->tag == Int) {
+ return rhs_t;
+ } else {
+ switch (compare_precision(lhs_t, rhs_t)) {
+ case NUM_PRECISION_LESS: return rhs_t;
+ case NUM_PRECISION_MORE: return lhs_t;
+ case NUM_PRECISION_EQUAL: return lhs_t;
+ default: {
+ if (can_compile_to_type(env, binop.rhs, lhs_t)) {
+ return lhs_t;
+ } else if (can_compile_to_type(env, binop.lhs, rhs_t)) {
+ return rhs_t;
+ }
+ break;
+ }
+ }
+ }
+
type_t *overall_t = (can_promote(rhs_t, lhs_t) ? lhs_t : (can_promote(lhs_t, rhs_t) ? rhs_t : NULL));
if (ast->tag == Multiply || ast->tag == Divide) {
binding_t *b = is_numeric_type(lhs_t) ? get_metamethod_binding(env, ast->tag, binop.lhs, binop.rhs, lhs_t)
@@ -1588,9 +1608,11 @@ PUREFUNC bool is_constant(env_t *env, ast_t *ast)
PUREFUNC bool can_compile_to_type(env_t *env, ast_t *ast, type_t *needed)
{
- if (needed->tag == OptionalType && ast->tag == None) {
+ if (is_incomplete_type(needed))
+ return false;
+
+ if (needed->tag == OptionalType && ast->tag == None)
return true;
- }
needed = non_optional(needed);
if (needed->tag == ArrayType && ast->tag == Array) {