From 90d3f429aa02cfc6581f0ad9d18f0d9e3f0daa71 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Thu, 28 Aug 2025 00:28:32 +0200 Subject: [PATCH] - `@test`/`@benchmark` on module would attach to interface and regular methods. --- releasenotes.md | 1 + src/compiler/parse_global.c | 9 +++++++-- src/compiler/sema_decls.c | 1 - .../{ => interfaces}/interface_multi.c3 | 0 test/test_suite/interfaces/interface_test.c3 | 18 ++++++++++++++++++ 5 files changed, 26 insertions(+), 3 deletions(-) rename test/test_suite/{ => interfaces}/interface_multi.c3 (100%) create mode 100644 test/test_suite/interfaces/interface_test.c3 diff --git a/releasenotes.md b/releasenotes.md index a1ed360d5..42f6e3d08 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -81,6 +81,7 @@ - Fix alignment on jump table. - Fix correct `?` after optional function name when reporting type errors. - Make `log` and `exp` no-strip. +- `@test`/`@benchmark` on module would attach to interface and regular methods. ### Stdlib changes - Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`. diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index e3557f775..8275474ea 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -1225,8 +1225,12 @@ PARSE_EXPR: static bool parse_attributes_for_global(ParseContext *c, Decl *decl) { Visibility visibility = c->unit->default_visibility; - if (decl->decl_kind == DECL_FUNC) decl->func_decl.attr_test = c->unit->test_by_default; - if (decl->decl_kind == DECL_FUNC) decl->func_decl.attr_benchmark = c->unit->benchmark_by_default; + // Transfer the test / benchmark properties + if (decl->decl_kind == DECL_FUNC && !decl->func_decl.attr_interface_method && !decl->func_decl.type_parent) + { + decl->func_decl.attr_test = c->unit->test_by_default; + decl->func_decl.attr_benchmark = c->unit->benchmark_by_default; + } decl->is_export = c->unit->export_by_default; bool is_builtin = false; bool is_cond; @@ -2692,6 +2696,7 @@ static inline Decl *parse_func_definition(ParseContext *c, AstId contracts, Func Decl *func = decl_calloc(); func->decl_kind = DECL_FUNC; func->func_decl.docs = contracts; + func->func_decl.attr_interface_method = parse_kind == FUNC_PARSE_INTERFACE; if (!parse_func_macro_header(c, func)) return poisoned_decl; if (func->name[0] == '@') { diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index beddfaa1c..5954ae357 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -954,7 +954,6 @@ static bool sema_analyse_interface(SemaContext *context, Decl *decl, bool *erase SEMA_ERROR(type_infoptr(method->func_decl.type_parent), "Interfaces should not be declared as methods."); return decl_poison(method); } - method->func_decl.attr_interface_method = true; bool erase = false; // Insert the first parameter, which is the implicit `void*` diff --git a/test/test_suite/interface_multi.c3 b/test/test_suite/interfaces/interface_multi.c3 similarity index 100% rename from test/test_suite/interface_multi.c3 rename to test/test_suite/interfaces/interface_multi.c3 diff --git a/test/test_suite/interfaces/interface_test.c3 b/test/test_suite/interfaces/interface_test.c3 new file mode 100644 index 000000000..f7a2a97e1 --- /dev/null +++ b/test/test_suite/interfaces/interface_test.c3 @@ -0,0 +1,18 @@ +module test; +import std; + +fn int main() +{ + return 0; +} + +module foo @test; +interface Bob +{ + fn void test(); +} +struct Foo +{ + int a; +} +fn void Foo.test(&self) {}