Recursive definition of tag not detected with nested tag/tagof #2790

This commit is contained in:
Christoffer Lerno
2026-01-22 19:16:54 +01:00
parent 0add42b0a0
commit e257500e03
3 changed files with 7 additions and 1 deletions

View File

@@ -104,6 +104,7 @@
- Using an optional type as generic parameter was not properly caught #2799 - 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 - Instantiating an alias of a user-defined type was not properly caught #2798
- Too deeply nested scopes was a fatal crash and not a regular semantic error. #2796 - Too deeply nested scopes was a fatal crash and not a regular semantic error. #2796
- Recursive definition of tag not detected with nested tag/tagof #2790
### Stdlib changes ### Stdlib changes
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads. - Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.

View File

@@ -3604,6 +3604,8 @@ static inline bool sema_expr_analyse_typecall(SemaContext *context, Expr *expr)
{ {
Expr *tag = exprptr(expr->call_expr.function); Expr *tag = exprptr(expr->call_expr.function);
expr->call_expr.arguments = sema_expand_vasplat_exprs(context, expr->call_expr.arguments); expr->call_expr.arguments = sema_expand_vasplat_exprs(context, expr->call_expr.arguments);
Decl *decl = tag->type_call_expr.type;
if (decl && !sema_analyse_decl(context, decl)) return false;
switch (tag->type_call_expr.property) switch (tag->type_call_expr.property)
{ {
case TYPE_PROPERTY_FROM_ORDINAL: case TYPE_PROPERTY_FROM_ORDINAL:
@@ -3626,7 +3628,6 @@ static inline bool sema_expr_analyse_typecall(SemaContext *context, Expr *expr)
{ {
RETURN_SEMA_ERROR(key, "The tag name should be a string constant."); RETURN_SEMA_ERROR(key, "The tag name should be a string constant.");
} }
Decl *decl = tag->type_call_expr.type;
const char *tagname = key->const_expr.bytes.ptr; const char *tagname = key->const_expr.bytes.ptr;
if (!decl) goto NOT_FOUND; if (!decl) goto NOT_FOUND;
ASSERT_SPAN(expr, decl->resolved_attributes); ASSERT_SPAN(expr, decl->resolved_attributes);

View File

@@ -0,0 +1,4 @@
struct Foo @tag("", Foo.tagof("")) // #error: Recursive definition of 'Foo'.
{
}
fn int main() => 1;