Skip to content

Commit ec19f42

Browse files
authored
checker, cgen: fix alias operator overloading (#15024)
1 parent 9231697 commit ec19f42

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

vlib/v/checker/infix.v

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
174174
} else {
175175
return_type = left_type
176176
}
177+
} else if left_final.has_method(node.op.str()) {
178+
if method := left_final.find_method(node.op.str()) {
179+
return_type = method.return_type
180+
} else {
181+
return_type = left_type
182+
}
177183
} else {
178184
left_name := c.table.type_to_str(left_type)
179185
right_name := c.table.type_to_str(right_type)
@@ -192,6 +198,12 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
192198
} else {
193199
return_type = right_type
194200
}
201+
} else if right_final.has_method(node.op.str()) {
202+
if method := right_final.find_method(node.op.str()) {
203+
return_type = method.return_type
204+
} else {
205+
return_type = right_type
206+
}
195207
} else {
196208
left_name := c.table.type_to_str(left_type)
197209
right_name := c.table.type_to_str(right_type)

vlib/v/gen/c/infix.v

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -664,14 +664,19 @@ fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) {
664664
g.expr(node.right)
665665
g.write(')')
666666
} else {
667-
method := g.table.find_method(left.sym, node.op.str()) or {
667+
mut method := ast.Fn{}
668+
mut method_name := ''
669+
if left.sym.has_method(node.op.str()) {
670+
method = left.sym.find_method(node.op.str()) or { ast.Fn{} }
671+
method_name = left.sym.cname + '_' + util.replace_op(node.op.str())
672+
} else if left.unaliased_sym.has_method(node.op.str()) {
673+
method = left.unaliased_sym.find_method(node.op.str()) or { ast.Fn{} }
674+
method_name = left.unaliased_sym.cname + '_' + util.replace_op(node.op.str())
675+
} else {
668676
g.gen_plain_infix_expr(node)
669677
return
670678
}
671-
left_styp := g.typ(left.typ.set_nr_muls(0))
672-
g.write(left_styp)
673-
g.write('_')
674-
g.write(util.replace_op(node.op.str()))
679+
g.write(method_name)
675680
g.write('(')
676681
g.op_arg(node.left, method.params[0].typ, left.typ)
677682
g.write(', ')
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
pub struct Vector {
2+
vec []f64
3+
}
4+
5+
pub fn (a Vector) + (b Vector) Vector {
6+
size := a.vec.len
7+
if size != b.vec.len {
8+
panic('unequal sizes')
9+
}
10+
mut c := []f64{len: size}
11+
for i in 0 .. size {
12+
c[i] = a.vec[i] + b.vec[i]
13+
}
14+
return Vector{
15+
vec: c
16+
}
17+
}
18+
19+
type Vec = Vector
20+
21+
fn test_alias_operator_overloading() {
22+
a := Vec{
23+
vec: [0.1, 0.2]
24+
}
25+
b := Vec{
26+
vec: [0.3, 0.2]
27+
}
28+
c := a + b
29+
println(c)
30+
assert c.vec == [0.4, 0.4]
31+
}

0 commit comments

Comments
 (0)