From 4538a1f50daee6a55d65aa0ee512c1aabf852b12 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Wed, 26 Mar 2025 18:04:00 +0100 Subject: [PATCH] - Correctly errors when a generic module contains a self-generic type. --- lib/std/collections/map.c3 | 0 releasenotes.md | 1 + src/compiler/sema_decls.c | 7 +++++ test/test_suite/generic/generic_self_ref.c3 | 29 +++++++++++++++++++++ 4 files changed, 37 insertions(+) delete mode 100644 lib/std/collections/map.c3 create mode 100644 test/test_suite/generic/generic_self_ref.c3 diff --git a/lib/std/collections/map.c3 b/lib/std/collections/map.c3 deleted file mode 100644 index e69de29bb..000000000 diff --git a/releasenotes.md b/releasenotes.md index 76d5fefe6..0c0bc583c 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -60,6 +60,7 @@ - Incorrectly allowed getting pointer to a macro #2049. - &self not runtime null-checked in macro #1827. - Bug when printing a boolean value as an integer using printf. +- Show error when a generic module contains a self-generic type. ### Stdlib changes - `new_*` functions in general moved to version without `new_` prefix. diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 8005c1d60..f8c102605 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -4497,6 +4497,13 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con Decl *alias = name_resolve.found; ASSERT(alias); Module *module = alias->unit->module; + + if (c->unit->module->generic_module == module) + { + sema_error_at(c, span, "This identifier is recursively using %s.", module->name->module); + return poisoned_decl; + } + unsigned parameter_count = vec_size(module->parameters); ASSERT(parameter_count > 0); if (parameter_count != vec_size(params)) diff --git a/test/test_suite/generic/generic_self_ref.c3 b/test/test_suite/generic/generic_self_ref.c3 new file mode 100644 index 000000000..7a8f1ea84 --- /dev/null +++ b/test/test_suite/generic/generic_self_ref.c3 @@ -0,0 +1,29 @@ +module gui::widget {Type}; +import gui::widget_types; +import std::collections::list; +import std::io; + +struct Widget +{ + int id; + Type type; + List {any} children; +} + +fn void Widget{Label}.draw(Widget* self) // #error: This identifier is recursively using gui::widget +{ + io::printfn("Hello Label"); +} + +module gui::widget_types; +import gui::widget; +struct Label +{ + String text; +} + +fn void main() +{ + Widget {int} y; + y.draw(); +} \ No newline at end of file