summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-20 11:16:11 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-20 11:16:11 +0000
commitdb690b368f7e05b242f2e775f620f35ab0df5bc3 (patch)
treec70d8e82bf81515e48b7bd2701595d6e62ce93e3 /src/parser
parentf027a812707d68ca0690b7544175b9f302dd57ad (diff)
Smart derives...
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/parser_core.c13
-rw-r--r--src/parser/parser_expr.c29
2 files changed, 35 insertions, 7 deletions
diff --git a/src/parser/parser_core.c b/src/parser/parser_core.c
index c3c91fe..acab268 100644
--- a/src/parser/parser_core.c
+++ b/src/parser/parser_core.c
@@ -585,17 +585,19 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char *
ASTNode *fdef = find_struct_def(ctx, ft);
if (fdef && fdef->type == NODE_ENUM)
{
- // Enum field: compare tags
+ // Enum field: compare tags (pointer access via auto-deref)
sprintf(cmp, "self.%s.tag == other.%s.tag", fn, fn);
}
else if (fdef && fdef->type == NODE_STRUCT)
{
- // Struct field: use _eq function
- sprintf(cmp, "%s__eq(&self.%s, other.%s)", ft, fn, fn);
+ // Struct field: use _eq function, pass addresses
+ // self.field is L-value, other.field is L-value (auto-deref from pointer)
+ // We need addresses of them: &self.field, &other.field
+ sprintf(cmp, "%s__eq(&self.%s, &other.%s)", ft, fn, fn);
}
else
{
- // Primitive or unknown: use ==
+ // Primitive or unknown: use == (auto-deref)
sprintf(cmp, "self.%s == other.%s", fn, fn);
}
strcat(body, cmp);
@@ -610,7 +612,8 @@ static ASTNode *generate_derive_impls(ParserContext *ctx, ASTNode *strct, char *
strcat(body, ";");
}
code = xmalloc(4096 + 1024);
- sprintf(code, "impl %s { fn eq(self, other: %s) -> bool { %s } }", name, name, body);
+ // Updated signature: other is a pointer T*
+ sprintf(code, "impl %s { fn eq(self, other: %s*) -> bool { %s } }", name, name, body);
}
else if (0 == strcmp(trait, "Debug"))
{
diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c
index 97d6218..a79bb21 100644
--- a/src/parser/parser_expr.c
+++ b/src/parser/parser_expr.c
@@ -4115,9 +4115,34 @@ ASTNode *parse_expr_prec(ParserContext *ctx, Lexer *l, Precedence min_prec)
}
}
+ // Handle RHS (Argument 2) Auto-Ref if needed
+ ASTNode *arg2 = rhs;
+ if (sig->total_args > 1 && sig->arg_types[1] &&
+ sig->arg_types[1]->kind == TYPE_POINTER)
+ {
+ Type *rt = rhs->type_info;
+ int is_rhs_ptr = (rt && rt->kind == TYPE_POINTER);
+ if (!is_rhs_ptr) // Need pointer, have value
+ {
+ int is_rvalue =
+ (rhs->type == NODE_EXPR_CALL || rhs->type == NODE_EXPR_BINARY ||
+ rhs->type == NODE_EXPR_STRUCT_INIT ||
+ rhs->type == NODE_EXPR_CAST || rhs->type == NODE_MATCH);
+
+ ASTNode *addr = ast_create(NODE_EXPR_UNARY);
+ addr->unary.op = is_rvalue ? xstrdup("&_rval") : xstrdup("&");
+ addr->unary.operand = rhs;
+ if (rt)
+ {
+ addr->type_info = type_new_ptr(rt);
+ }
+ arg2 = addr;
+ }
+ }
+
call->call.args = arg1;
- arg1->next = rhs;
- rhs->next = NULL;
+ arg1->next = arg2;
+ arg2->next = NULL;
call->type_info = sig->ret_type;
call->resolved_type = type_to_string(sig->ret_type);