Detect recursive creation of generics #2366.

This commit is contained in:
Christoffer Lerno
2025-08-05 02:55:32 +02:00
parent 5292e08cd6
commit 229fdd6193
4 changed files with 23 additions and 0 deletions

View File

@@ -14,6 +14,7 @@
- Reduce allocated Vmem for the compiler on 32 bit machines.
- Bug causing a compiler error when parsing a broken lambda inside of an expression.
- Fixed: regression in comments for `@deprecated` and `@pure`.
- Detect recursive creation of generics #2366.
### Stdlib changes
- Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`.

View File

@@ -48,6 +48,7 @@ typedef uint16_t FileId;
#define MAX_BITSTRUCT 0x1000
#define MAX_MEMBERS ((StructIndex)1) << 15
#define MAX_ALIGNMENT ((ArrayIndex)(((uint64_t)2) << 28))
#define MAX_GENERIC_DEPTH 32
#define MAX_PRIORITY 0xFFFF
#define MAX_TYPE_SIZE UINT32_MAX
#define MAX_GLOBAL_DECL_STACK (65536)
@@ -1931,6 +1932,7 @@ typedef struct
Linking linking;
GlobalContext context;
const char *obj_output;
int generic_depth;
} CompilerState;
extern CompilerState compiler;

View File

@@ -450,8 +450,14 @@ INLINE bool sema_resolve_generic_type(SemaContext *context, TypeInfo *type_info)
ASSERT_SPAN(inner, inner->resolve_status == RESOLVE_NOT_DONE);
bool was_recursive = false;
if (compiler.generic_depth >= MAX_GENERIC_DEPTH)
{
RETURN_SEMA_ERROR(type_info, "Generic resolution of this type has become deeply nested, it was aborted after reaching %d recursions.", compiler.generic_depth);
}
compiler.generic_depth++;
Decl *type = sema_analyse_parameterized_identifier(context, inner->unresolved.path, inner->unresolved.name,
inner->span, type_info->generic.params, &was_recursive);
compiler.generic_depth--;
if (!decl_ok(type)) return false;
if (!sema_analyse_decl(context, type)) return false;
type_info->type = type->type;

View File

@@ -0,0 +1,14 @@
module test;
import test1;
fn int main() => 0;
Aa {int} a;
module test1 {Type};
import test2;
alias Cc = Aa {Bb {Type}}; // #error: Generic resolution of this type has become deeply nested
struct Aa {Type a;}
module test2 {Type};
struct Bb {Type b;}