浏览代码

Fix crash when proc return type is undeclared parapoly variable

Disallow the declaration of new parapoly variables in return types, when
the procedure's parapoly scope is itself. This happens if e.g.:
`foo :: proc() -> $T`.

Closes #3949, #4294, #4563
Roland Kovacs 9 月之前
父节点
当前提交
f2f952b344
共有 2 个文件被更改,包括 9 次插入1 次删除
  1. 8 1
      src/check_type.cpp
  2. 1 0
      src/checker.hpp

+ 8 - 1
src/check_type.cpp

@@ -2440,8 +2440,12 @@ gb_internal bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc
 	bool success = true;
 	bool success = true;
 	isize specialization_count = 0;
 	isize specialization_count = 0;
 	Type *params  = check_get_params(c, c->scope, pt->params, &variadic, &variadic_index, &success, &specialization_count, operands);
 	Type *params  = check_get_params(c, c->scope, pt->params, &variadic, &variadic_index, &success, &specialization_count, operands);
-	Type *results = check_get_results(c, c->scope, pt->results);
 
 
+	bool no_poly_return = c->disallow_polymorphic_return_types;
+	c->disallow_polymorphic_return_types = c->scope == c->polymorphic_scope;
+	// NOTE(zen3ger): if the parapoly scope is the current proc's scope, then the return types shall not declare new poly vars
+	Type *results = check_get_results(c, c->scope, pt->results);
+	c->disallow_polymorphic_return_types = no_poly_return;
 
 
 	isize param_count = 0;
 	isize param_count = 0;
 	isize result_count = 0;
 	isize result_count = 0;
@@ -3383,6 +3387,9 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T
 		}
 		}
 		Type *t = alloc_type_generic(ctx->scope, 0, token.string, specific);
 		Type *t = alloc_type_generic(ctx->scope, 0, token.string, specific);
 		if (ctx->allow_polymorphic_types) {
 		if (ctx->allow_polymorphic_types) {
+			if (ctx->disallow_polymorphic_return_types) {
+				error(ident, "Undeclared polymorphic parameter '%.*s' in return type", LIT(token.string));
+			}
 			Scope *ps = ctx->polymorphic_scope;
 			Scope *ps = ctx->polymorphic_scope;
 			Scope *s = ctx->scope;
 			Scope *s = ctx->scope;
 			Scope *entity_scope = s;
 			Scope *entity_scope = s;

+ 1 - 0
src/checker.hpp

@@ -521,6 +521,7 @@ struct CheckerContext {
 	bool       in_enum_type;
 	bool       in_enum_type;
 	bool       collect_delayed_decls;
 	bool       collect_delayed_decls;
 	bool       allow_polymorphic_types;
 	bool       allow_polymorphic_types;
+	bool       disallow_polymorphic_return_types; // NOTE(zen3ger): no poly type decl in return types
 	bool       no_polymorphic_errors;
 	bool       no_polymorphic_errors;
 	bool       hide_polymorphic_errors;
 	bool       hide_polymorphic_errors;
 	bool       in_polymorphic_specialization;
 	bool       in_polymorphic_specialization;