harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit b278149b0a839bce086321d7880c175d1d5db9e1
parent 40159a9a72927713aa6e16fd0f48b2b1c110414a
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Wed, 10 Feb 2021 12:44:18 -0500

Expand type hinting

Diffstat:
Msrc/check.c | 17+++++++++++------
Msrc/type_store.c | 2+-
2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -190,10 +190,11 @@ check_expr_alloc(struct context *ctx, expr->alloc.expr = xcalloc(sizeof(struct expression), 1); expr->result = type_store_lookup_atype(ctx->store, aexpr->alloc.type); - check_expression(ctx, aexpr->alloc.expr, expr->alloc.expr, expr->result); enum type_storage storage = type_dealias(expr->result)->storage; switch (storage) { case TYPE_STORAGE_POINTER: + check_expression(ctx, aexpr->alloc.expr, expr->alloc.expr, + expr->result->pointer.referent); if (aexpr->alloc.cap != NULL) { // We can't just expect(aexpr->alloc.cap != NULL) // because we want to use aexpr->alloc.cap->loc @@ -203,6 +204,8 @@ check_expr_alloc(struct context *ctx, } break; case TYPE_STORAGE_SLICE: + check_expression(ctx, aexpr->alloc.expr, expr->alloc.expr, + expr->result); if (aexpr->alloc.cap != NULL) { expr->alloc.cap = xcalloc(sizeof(struct expression), 1); check_expression(ctx, aexpr->alloc.cap, expr->alloc.cap, @@ -350,7 +353,6 @@ check_expr_assign(struct context *ctx, struct expression *value = xcalloc(1, sizeof(struct expression)); check_expression(ctx, aexpr->assign.object, object, NULL); - check_expression(ctx, aexpr->assign.value, value, object->result); expr->assign.op = aexpr->assign.op; @@ -361,12 +363,15 @@ check_expr_assign(struct context *ctx, expect(&aexpr->loc, !(object->result->pointer.flags & PTR_NULLABLE), "Cannot dereference nullable pointer type"); + check_expression(ctx, aexpr->assign.value, value, + object->result->pointer.referent); expect(&aexpr->loc, type_is_assignable(object->result->pointer.referent, value->result), "Value type is not assignable to pointer type"); value = lower_implicit_cast(object->result->pointer.referent, value); } else { + check_expression(ctx, aexpr->assign.value, value, object->result); assert(object->type == EXPR_ACCESS || object->type == EXPR_SLICE); // Invariant expect(&aexpr->loc, !(object->result->flags & TYPE_CONST), @@ -986,12 +991,12 @@ check_expr_if(struct context *ctx, check_expression(ctx, aexpr->_if.cond, cond, &builtin_type_bool); true_branch = xcalloc(1, sizeof(struct expression)); - check_expression(ctx, aexpr->_if.true_branch, true_branch, NULL); + check_expression(ctx, aexpr->_if.true_branch, true_branch, hint); if (aexpr->_if.false_branch) { false_branch = xcalloc(1, sizeof(struct expression)); check_expression(ctx, aexpr->_if.false_branch, - false_branch, NULL); + false_branch, hint); if (true_branch->terminates && false_branch->terminates) { expr->terminates = true; @@ -1139,7 +1144,7 @@ check_expr_match(struct context *ctx, _case->value = xcalloc(1, sizeof(struct expression)); _case->type = ctype; - check_expression(ctx, acase->value, _case->value, NULL); + check_expression(ctx, acase->value, _case->value, hint); if (acase->name) { scope_pop(&ctx->scope, TR_CHECK); @@ -1473,7 +1478,7 @@ check_expr_switch(struct context *ctx, } _case->value = xcalloc(1, sizeof(struct expression)); - check_expression(ctx, acase->value, _case->value, type); + check_expression(ctx, acase->value, _case->value, hint); if (_case->value->terminates) { continue; } diff --git a/src/type_store.c b/src/type_store.c @@ -451,7 +451,7 @@ type_init_from_atype(struct type_store *store, if (avalue->value != NULL) { struct expression in, out; check_expression(store->check_context, - avalue->value, &in, NULL); + avalue->value, &in, storage); enum eval_result r = eval_expr(store->check_context, &in, &out); // TODO: Bubble this up