2
0
Эх сурвалжийг харах

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.
Roland Kovacs 1 жил өмнө
parent
commit
dda89a69bf
1 өөрчлөгдсөн 21 нэмэгдсэн , 0 устгасан
  1. 21 0
      src/check_type.cpp

+ 21 - 0
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;
 		}