Browse Source

fixes #10198 (this time for real)

Aleksandr Kuzmenko 4 năm trước cách đây
mục cha
commit
5c34a416dd

+ 13 - 12
src/core/tUnification.ml

@@ -155,6 +155,17 @@ module Monomorph = struct
 		m.tm_constraints <- []
 
 	let rec bind m t =
+		let propagate_constraints() =
+			(* Due to recursive constraints like in #9603, we tentatively bind the monomorph to the type we're checking
+			   against before checking the constraints. *)
+			m.tm_type <- Some t;
+			let monos,kind = classify_constraints' m in
+			Std.finally (fun () -> m.tm_type <- None) (fun () -> check_constraints kind t) ();
+			(* If the monomorph we're binding to has other yet unbound monomorphs, constrain them to our target type (issue #9640) .*)
+			List.iter (fun m2 ->
+				constrain_to_type m2 None t;
+			) monos;
+		in
 		begin match t with
 		| TAnon _ when List.mem MOpenStructure m.tm_constraints ->
 			(* If we assign an open structure monomorph to another structure, the semantics want us to merge the
@@ -164,24 +175,14 @@ module Monomorph = struct
 		| TMono m2 ->
 			if m != m2 then begin match m2.tm_type with
 			| None ->
+				propagate_constraints();
 				List.iter (fun constr -> m2.tm_constraints <- constr :: m2.tm_constraints) m.tm_constraints;
-				(* If the monomorph we're binding to has other yet unbound monomorphs, constrain them to our target type (issue #9640) .*)
-				let mono_constraints,_ = classify_constraints' m in
-				List.iter (fun m3 -> constrain_to_type m3 None t) mono_constraints;
 				do_bind m t;
 			| Some t ->
 				bind m t
 			end
 		| _ ->
-			(* Due to recursive constraints like in #9603, we tentatively bind the monomorph to the type we're checking
-			   against before checking the constraints. *)
-			m.tm_type <- Some t;
-			let monos,kind = classify_constraints' m in
-			Std.finally (fun () -> m.tm_type <- None) (fun () -> check_constraints kind t) ();
-			(* If the monomorph we're binding to has other yet unbound monomorphs, constrain them to our target type (issue #9640) .*)
-			List.iter (fun m2 ->
-				constrain_to_type m2 None t;
-			) monos;
+			propagate_constraints();
 			do_bind m t
 		end
 

+ 17 - 0
tests/misc/projects/Issue10198/WithAbstractCast.hx

@@ -0,0 +1,17 @@
+class WithAbstractCast {
+	static function main() {
+		var foo:Vector<Int> = null;
+		var bar:Vector<String> = Vector.fromIterable(foo);
+	}
+}
+
+abstract Vector<T>(Array<T>) {
+	@:from static public function fromVector<T1, R1:T1>(v:Vector<R1>):Vector<T1>
+		return cast v;
+
+	static public function fromIterable<T2, R2:T2>(v:Iterable<R2>):Vector<T2>
+		return null;
+
+	@:to public function toArray()
+		return this.copy();
+}

+ 1 - 0
tests/misc/projects/Issue10198/compile-with-abstract-cast-fail.hxml

@@ -0,0 +1 @@
+--main WithAbstractCast

+ 3 - 0
tests/misc/projects/Issue10198/compile-with-abstract-cast-fail.hxml.stderr

@@ -0,0 +1,3 @@
+WithAbstractCast.hx:4: characters 3-53 : error: Int should be String
+WithAbstractCast.hx:4: characters 3-53 : ... have: Vector<Int>
+WithAbstractCast.hx:4: characters 3-53 : ... want: Vector<String>