From 6a78864b6cce3074048a0c9a3547ce4757e934ce Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 22 Jan 2026 13:50:57 +0100 Subject: [PATCH] Instantiating an alias of a user-defined type was not properly caught #2798 --- releasenotes.md | 1 + src/compiler/sema_types.c | 14 +++++++------- .../generic/generic_instantiate_alias.c3 | 9 +++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 test/test_suite/generic/generic_instantiate_alias.c3 diff --git a/releasenotes.md b/releasenotes.md index dba3e8d8f..03ab53302 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -101,6 +101,7 @@ - Casting const bytes to vector with different element size was broken #2787 - Unable to access fields of a const inline enum with an aggregate underlying type. #2802 - Using an optional type as generic parameter was not properly caught #2799 +- Instantiating an alias of a user-defined type was not properly caught #2798 ### Stdlib changes - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 3a84b1c6b..01ef5372d 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -442,15 +442,15 @@ INLINE bool sema_resolve_generic_type(SemaContext *context, TypeInfo *type_info) { RETURN_SEMA_ERROR(inner, "Parameterization required a concrete type name here."); } - if (inner->resolve_status == RESOLVE_DONE) + switch (inner->resolve_status) { - if (!type_is_user_defined(inner->type)) - { - RETURN_SEMA_ERROR(inner, "A user defined type was expected here, not %s.", type_quoted_error_string(inner->type)); - } + case RESOLVE_DONE: + RETURN_SEMA_ERROR(inner, "A user-defined generic type was expected here, but the type was %s.", type_quoted_error_string(inner->type)); + case RESOLVE_RUNNING: + RETURN_SEMA_ERROR(inner, "Resolving the type %s entered a recursive loop.", type_quoted_error_string(inner->type)); + default: + break; } - ASSERT_SPAN(inner, inner->resolve_status == RESOLVE_NOT_DONE); - bool was_recursive = false; if (compiler.generic_depth >= MAX_GENERIC_DEPTH) { diff --git a/test/test_suite/generic/generic_instantiate_alias.c3 b/test/test_suite/generic/generic_instantiate_alias.c3 new file mode 100644 index 000000000..771a26ce1 --- /dev/null +++ b/test/test_suite/generic/generic_instantiate_alias.c3 @@ -0,0 +1,9 @@ +import std; +fn void a() +{ + usz{} i = Z; // #error: A user-defined generic type was expected here, but the type was 'usz' (ulong) +} +fn int main() +{ + return 0; +} \ No newline at end of file