From 9bf933ae314d78b612d74d5fbf4c6e578f5ebd0b Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 23 Aug 2025 23:41:32 +0200 Subject: [PATCH] - `has_tagof` on tagged lambdas returns false #2432 --- releasenotes.md | 1 + src/compiler/compiler_internal.h | 6 ++++++ src/compiler/sema_expr.c | 4 ++-- test/unit/regression/function_tag.c3 | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 test/unit/regression/function_tag.c3 diff --git a/releasenotes.md b/releasenotes.md index 68d7303cf..e084e8457 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -63,6 +63,7 @@ - Taking the address of a label would cause a crash. #2430 - `@tag` was not allowed to repeat. - Lambdas on the top level were not exported by default. #2428 +- `has_tagof` on tagged lambdas returns false #2432 ### Stdlib changes - Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`. diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 08c57e4e5..abfbfb801 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -4341,6 +4341,12 @@ INLINE bool expr_is_const_fault(Expr *expr) return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_FAULT; } +INLINE bool expr_is_const_ref(Expr *expr) +{ + ASSERT(expr->resolve_status == RESOLVE_DONE); + return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_REF; +} + INLINE bool expr_is_const_pointer(Expr *expr) { ASSERT(expr->resolve_status == RESOLVE_DONE); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 5fd5a4bd3..fa08bb8fb 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -5972,9 +5972,9 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bo { return sema_expr_analyse_type_access(context, expr, parent->type_expr->type, identifier, missing_ref); } - if (parent->expr_kind == EXPR_IDENTIFIER) + if (parent->expr_kind == EXPR_IDENTIFIER || expr_is_const_ref(parent)) { - Decl *decl = parent->ident_expr; + Decl *decl = parent->expr_kind == EXPR_IDENTIFIER ? parent->ident_expr : parent->const_expr.global_ref; switch (decl->decl_kind) { case DECL_FUNC: diff --git a/test/unit/regression/function_tag.c3 b/test/unit/regression/function_tag.c3 new file mode 100644 index 000000000..893b6cb8c --- /dev/null +++ b/test/unit/regression/function_tag.c3 @@ -0,0 +1,14 @@ +module function_tag; + +macro bool @has_tagof_1(#function) +{ + return #function.has_tagof("some-tag"); +} + +fn void tagged_function() @tag("some-tag", true) {} + +fn void function_tag() @test +{ + assert(@has_tagof_1(tagged_function)); + assert(@has_tagof_1(fn void() @tag("some-tag", true) {} )); +}