aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoland Kovacs <zen3ger@tutanota.com>2024-08-07 21:37:34 +0200
committerRoland Kovacs <zen3ger@tutanota.com>2024-08-08 19:50:05 +0200
commitdda89a69bf131ea4331b9c494a4afe4a420276bc (patch)
tree68f60b782b0bb9c7d5492bdf5bd07d1bd4cd007b /src
parent796feeead9ef2625351ec6745ce7cbc5dde8a911 (diff)
Check if procedure parameter type declares polymorphic args
When a procedure parameter's type was declared in an imported package the type checker correctly resolved to the parametric type, but it did not check if the expression that refers to that type conforms to a polymorphic type declaration. This error was not detected if the procedure was unused, since it was marked as polymorphic, where further type check is done on instantiation.
Diffstat (limited to 'src')
-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;
}