aboutsummaryrefslogtreecommitdiff
path: root/src/check_type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/check_type.cpp')
-rw-r--r--src/check_type.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 41de8ccce..5f456fb31 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -2309,8 +2309,28 @@ gb_internal Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_res
return tuple;
}
+gb_internal void check_procedure_param_polymorphic_type(CheckerContext *ctx, Type *type, Ast *type_expr) {
+ GB_ASSERT_NOT_NULL(type_expr);
+ if (type == nullptr || ctx->in_polymorphic_specialization) { return; }
+ if (!is_type_polymorphic_record_unspecialized(type)) { return; }
+
+ bool invalid_polymorpic_type_use = false;
+ switch (type_expr->kind) {
+ case_ast_node(pt, Ident, type_expr);
+ invalid_polymorpic_type_use = true;
+ case_end;
+ case_ast_node(pt, SelectorExpr, type_expr);
+ invalid_polymorpic_type_use = true;
+ case_end;
+ }
+ if (invalid_polymorpic_type_use) {
+ gbString expr_str = expr_to_string(type_expr);
+ defer (gb_string_free(expr_str));
+ error(type_expr, "Invalid use of a non-specialized polymorphic type '%s'", expr_str);
+ }
+}
// NOTE(bill): 'operands' is for generating non generic procedure type
gb_internal bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array<Operand> const *operands) {
@@ -2433,6 +2453,7 @@ gb_internal bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc
if (e->kind != Entity_Variable) {
is_polymorphic = true;
} else if (is_type_polymorphic(e->type)) {
+ check_procedure_param_polymorphic_type(c, e->type, e->Variable.type_expr);
is_polymorphic = true;
}