From c2a64e2fd76d77383c9a0253b4d4876c790898e4 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Fri, 23 Jan 2026 14:53:18 +0200 Subject: [PATCH] cgen: fix `+=` overloading for aliases, regression after 29e60da #23967 (fix #26416) (#26423) --- vlib/v/gen/c/assign.v | 24 +++++++------- ...nt_operator_overloading_issue_26416_test.v | 31 +++++++++++++++++++ 2 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 vlib/v/tests/aliases/alias_parent_operator_overloading_issue_26416_test.v diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 0ab37c6e7..929a4b358 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -704,6 +704,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { } pos := g.out.len g.expr(left) + struct_info := g.table.final_sym(var_type) if left_sym.info is ast.Struct && left_sym.info.generic_types.len > 0 { concrete_types := left_sym.info.concrete_types mut method_name := left_sym.cname + '_' + util.replace_op(extracted_op) @@ -725,19 +726,16 @@ 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 left_sym.kind == .alias && struct_info.kind == .struct + && 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) diff --git a/vlib/v/tests/aliases/alias_parent_operator_overloading_issue_26416_test.v b/vlib/v/tests/aliases/alias_parent_operator_overloading_issue_26416_test.v new file mode 100644 index 000000000..f303281e2 --- /dev/null +++ b/vlib/v/tests/aliases/alias_parent_operator_overloading_issue_26416_test.v @@ -0,0 +1,31 @@ +pub struct Vec3 { +pub: + x f64 + y f64 + z f64 +} + +pub fn (u Vec3) + (v Vec3) Vec3 { + return Vec3{u.x + v.x, u.y + v.y, u.z + v.z} +} + +pub type Color3 = Vec3 + +pub fn (u Color3) + (v Color3) Color3 { + return Color3{100 + u.x + v.x, 200 + u.y + v.y, 300 + u.z + v.z} +} + +fn color(x int) Color3 { + return Color3{1, 2, 3} +} + +fn test_main() { + mut c := Color3{1, 2, 3} + for _ in 0 .. 3 { + c += color(123) + } + println(c) + assert c.x == 304.0 // make sure that the overloaded + for Color3 was called, and NOT the overloaded + for Vec3. + assert c.y == 608.0 + assert c.z == 912.0 +} -- 2.39.5