aboutsummaryrefslogtreecommitdiff
path: root/src/check_decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/check_decl.cpp')
-rw-r--r--src/check_decl.cpp55
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);