mirror of
https://github.com/vlang/v.git
synced 2025-08-04 10:17:22 -04:00
checker,cgen: implement alias operator overloading for generic struct parent type (fix #23965) (#23967)
This commit is contained in:
parent
bd2ec679f0
commit
29e60da614
@ -797,20 +797,28 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
|
||||
if left_sym.kind == .struct && (left_sym.info as ast.Struct).generic_types.len > 0 {
|
||||
continue
|
||||
}
|
||||
if method := left_sym.find_method(extracted_op) {
|
||||
if method := left_sym.find_method_with_generic_parent(extracted_op) {
|
||||
if method.return_type != left_type_unwrapped {
|
||||
c.error('operator `${extracted_op}` must return `${left_name}` to be used as an assignment operator',
|
||||
node.pos)
|
||||
}
|
||||
} else {
|
||||
if !parent_sym.is_primitive() {
|
||||
if left_name == right_name {
|
||||
c.error('undefined operation `${left_name}` ${extracted_op} `${right_name}`',
|
||||
node.pos)
|
||||
} else {
|
||||
c.error('mismatched types `${left_name}` and `${right_name}`',
|
||||
if method := parent_sym.find_method_with_generic_parent(extracted_op) {
|
||||
if parent_sym.kind == .alias
|
||||
&& (parent_sym.info as ast.Alias).parent_type != method.return_type {
|
||||
c.error('operator `${extracted_op}` must return `${left_name}` to be used as an assignment operator',
|
||||
node.pos)
|
||||
}
|
||||
} else {
|
||||
if !parent_sym.is_primitive() {
|
||||
if left_name == right_name {
|
||||
c.error('undefined operation `${left_name}` ${extracted_op} `${right_name}`',
|
||||
node.pos)
|
||||
} else {
|
||||
c.error('mismatched types `${left_name}` and `${right_name}`',
|
||||
node.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -674,6 +674,19 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
||||
g.write(';')
|
||||
}
|
||||
return
|
||||
} else if left_sym.kind == .alias && g.table.final_sym(var_type).kind == .struct {
|
||||
struct_info := g.table.final_sym(var_type)
|
||||
if struct_info.info is ast.Struct && struct_info.info.generic_types.len > 0 {
|
||||
mut method_name := struct_info.cname + '_' + util.replace_op(extracted_op)
|
||||
method_name = g.generic_fn_name(struct_info.info.concrete_types,
|
||||
method_name)
|
||||
g.write(' = ${method_name}(')
|
||||
g.expr(left)
|
||||
g.write(', ')
|
||||
g.expr(val)
|
||||
g.writeln(');')
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if g.table.final_sym(g.unwrap_generic(var_type)).kind == .array_fixed {
|
||||
g.go_back_to(pos)
|
||||
|
@ -0,0 +1,18 @@
|
||||
import math.vec
|
||||
|
||||
type V2 = vec.Vec2[f32]
|
||||
|
||||
fn test_alias_generic_parent_operator_overloading() {
|
||||
a := V2{1, 1}
|
||||
b := V2{10, 20}
|
||||
|
||||
mut c := a + b
|
||||
assert c.x == 11.0
|
||||
assert c.y == 21.0
|
||||
dump(c)
|
||||
|
||||
c += a
|
||||
assert c.x == 12.0
|
||||
assert c.y == 22.0
|
||||
dump(c)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user