diff options
| author | Roland Kovacs <zen3ger@tutanota.com> | 2024-08-07 21:37:34 +0200 |
|---|---|---|
| committer | Roland Kovacs <zen3ger@tutanota.com> | 2024-08-08 19:50:05 +0200 |
| commit | dda89a69bf131ea4331b9c494a4afe4a420276bc (patch) | |
| tree | 68f60b782b0bb9c7d5492bdf5bd07d1bd4cd007b | |
| parent | 796feeead9ef2625351ec6745ce7cbc5dde8a911 (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.
| -rw-r--r-- | src/check_type.cpp | 21 |
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; } |