diff options
Diffstat (limited to 'src/check_decl.cpp')
| -rw-r--r-- | src/check_decl.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp index da2214d89..1a6fad918 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -338,7 +338,7 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, if (type_expr) { Type *t = check_type(ctx, type_expr); - if (!is_type_constant_type(t)) { + if (!is_type_constant_type(t) && !is_type_proc(t)) { gbString str = type_to_string(t); error(type_expr, "Invalid constant type '%s'", str); gb_string_free(str); @@ -392,6 +392,25 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, } if (entity != nullptr) { + if (e->type != nullptr) { + Operand x = {}; + x.type = entity->type; + x.mode = Addressing_Variable; + if (!check_is_assignable_to(ctx, &x, e->type)) { + gbString expr_str = expr_to_string(init); + gbString op_type_str = type_to_string(entity->type); + gbString type_str = type_to_string(e->type); + error(e->token, + "Cannot assign '%s' of type '%s' to '%s'", + expr_str, + op_type_str, + type_str); + + gb_string_free(type_str); + gb_string_free(op_type_str); + gb_string_free(expr_str); + } + } // NOTE(bill): Override aliased entity switch (entity->kind) { @@ -583,11 +602,45 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { check_open_scope(ctx, pl->type); defer (check_close_scope(ctx)); + Type *decl_type = nullptr; + + if (d->type_expr != nullptr) { + decl_type = check_type(ctx, d->type_expr); + if (!is_type_proc(decl_type)) { + gbString str = type_to_string(decl_type); + error(d->type_expr, "Expected a procedure type, got '%s'", str); + gb_string_free(str); + } + } + auto tmp_ctx = *ctx; tmp_ctx.allow_polymorphic_types = true; + if (decl_type != nullptr) { + tmp_ctx.type_hint = decl_type; + } check_procedure_type(&tmp_ctx, proc_type, pl->type); + if (decl_type != nullptr) { + Operand x = {}; + x.type = e->type; + x.mode = Addressing_Variable; + if (!check_is_assignable_to(ctx, &x, decl_type)) { + gbString expr_str = expr_to_string(d->proc_lit); + gbString op_type_str = type_to_string(e->type); + gbString type_str = type_to_string(decl_type); + error(e->token, + "Cannot assign '%s' of type '%s' to '%s'", + expr_str, + op_type_str, + type_str); + + gb_string_free(type_str); + gb_string_free(op_type_str); + gb_string_free(expr_str); + } + } + TypeProc *pt = &proc_type->Proc; AttributeContext ac = make_attribute_context(e->Procedure.link_prefix); |