Просмотр исходного кода

fixed assignment of the result of `@:op(A += B)` if the overloading method has no expr (closes #10209)

Aleksandr Kuzmenko 4 лет назад
Родитель
Сommit
c19d3e0711
2 измененных файлов с 21 добавлено и 2 удалено
  1. 8 2
      src/typing/operators.ml
  2. 13 0
      tests/unit/src/unit/issues/Issue10209.hx

+ 8 - 2
src/typing/operators.ml

@@ -468,7 +468,12 @@ let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op with_type
 							error (Printf.sprintf "The result of this operation (%s) is not compatible with declared return type %s" (st t_expected) (st tret)) p
 				end;
 			end;
-			BinopResult.create_normal op e1 e2 tret needs_assign swapped p
+			(*
+				If the `@:op`-field has no expr, then user wants the semantics of an underlying type.
+				which is supposed to make an assignment for AssignOp's.
+				Hence we use `is_assign_op` here instead of `needs_assign`.
+			*)
+			BinopResult.create_normal op e1 e2 tret is_assign_op swapped p
 		end else if swapped then begin
 			let vr = new value_reference ctx in
 			let e2' = vr#as_var "lhs" e2 in
@@ -488,7 +493,8 @@ let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op with_type
 		| _ ->
 			()
 	end;
-	let rec loop find_op ol = match ol with
+	let rec loop find_op ol =
+		match ol with
 		| (op_cf,cf) :: ol when op_cf = find_op ->
 			let is_impl = has_class_field_flag cf CfImpl in
 			begin

+ 13 - 0
tests/unit/src/unit/issues/Issue10209.hx

@@ -0,0 +1,13 @@
+package unit.issues;
+
+class Issue10209 extends Test {
+	function test() {
+		var s:AStr = 'hello';
+		s += ', world';
+		eq('hello, world', s);
+	}
+}
+
+private abstract AStr(String) from String to String {
+	@:op(A += B) @:commutative static function assignAdd(a:AStr, b:String):AStr;
+}