summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-24 12:29:20 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-24 12:29:20 +0000
commit08558d8cdab7598c4a2e077bd665b49bfee18a79 (patch)
tree941dfa3bfa4b51ca3b0a0dd0ca90f8663832460d
parent812fe9cbe124bf39a06f58a538c8c01f7402fb09 (diff)
Fix for #107
-rw-r--r--src/codegen/codegen_decl.c15
-rw-r--r--src/codegen/codegen_utils.c18
-rw-r--r--tests/features/test_traits_suite.zc21
3 files changed, 51 insertions, 3 deletions
diff --git a/src/codegen/codegen_decl.c b/src/codegen/codegen_decl.c
index 18d81f5..b82e1af 100644
--- a/src/codegen/codegen_decl.c
+++ b/src/codegen/codegen_decl.c
@@ -953,7 +953,20 @@ void emit_impl_vtables(ParserContext *ctx, FILE *out)
ASTNode *m = node->impl_trait.methods;
while (m)
{
- const char *orig = parse_original_method_name(m->func.name);
+ // Calculate expected prefix: Struct__Trait_
+ char prefix[256];
+ sprintf(prefix, "%s__%s_", strct, trait);
+ const char *orig = m->func.name;
+ if (strncmp(orig, prefix, strlen(prefix)) == 0)
+ {
+ orig += strlen(prefix);
+ }
+ else
+ {
+ // Fallback if mangling schema differs (shouldn't happen)
+ orig = parse_original_method_name(m->func.name);
+ }
+
fprintf(out, ".%s = (__typeof__(((%s_VTable*)0)->%s))%s__%s_%s", orig, trait, orig,
strct, trait, orig);
if (m->next)
diff --git a/src/codegen/codegen_utils.c b/src/codegen/codegen_utils.c
index a7e4925..3169eba 100644
--- a/src/codegen/codegen_utils.c
+++ b/src/codegen/codegen_utils.c
@@ -519,8 +519,22 @@ char *extract_call_args(const char *args)
// Parse original method name from mangled name.
const char *parse_original_method_name(const char *mangled)
{
- const char *last = strrchr(mangled, '_');
- return last ? last + 1 : mangled;
+ const char *sep = strstr(mangled, "__");
+ if (!sep)
+ {
+ return mangled;
+ }
+
+ // Let's iterate to find the last `__`.
+ const char *last_double = NULL;
+ const char *p = mangled;
+ while ((p = strstr(p, "__")))
+ {
+ last_double = p;
+ p += 2;
+ }
+
+ return last_double ? last_double + 2 : mangled;
}
// Replace string type in arguments.
diff --git a/tests/features/test_traits_suite.zc b/tests/features/test_traits_suite.zc
index 7a2a262..8410de8 100644
--- a/tests/features/test_traits_suite.zc
+++ b/tests/features/test_traits_suite.zc
@@ -121,3 +121,24 @@ fn print_default_shape(s: Shape = &g_def_circle) {
test "implicit_trait_cast_default" {
print_default_shape();
}
+
+trait UnderscoreTest {
+ fn method_with_underscores_123(self) -> int;
+}
+
+struct UnderscoreStruct {
+ val: int;
+}
+
+impl UnderscoreTest for UnderscoreStruct {
+ fn method_with_underscores_123(self) -> int {
+ return self.val;
+ }
+}
+
+test "trait_underscores" {
+ var u = UnderscoreStruct { val: 100 };
+ var t: UnderscoreTest = &u;
+
+ assert(t.method_with_underscores_123() == 100, "Method with underscores call failed");
+}