Преглед изворни кода

don't hang on abstracts with Dynamic parameter (fixes #8588)

Aleksandr Kuzmenko пре 6 година
родитељ
комит
c5f8a3ca80

+ 9 - 2
src/core/type.ml

@@ -1770,10 +1770,17 @@ let rec fast_eq_mono ml a b =
 	| _ , _ ->
 		false
 
-let rec fast_eq_anon a b =
-	if fast_eq_check fast_eq_anon a b then
+let rec fast_eq_anon ?(mono_equals_dynamic=false) a b =
+	if fast_eq_check (fast_eq_anon ~mono_equals_dynamic) a b then
 		true
 	else match a , b with
+	(*
+		`mono_equals_dynamic` is here because of https://github.com/HaxeFoundation/haxe/issues/8588#issuecomment-520138371
+		Generally unbound monomorphs should not be considered equal to anything,
+		because it's unknown, which types they would be bound to.
+	*)
+	| t, TMono { contents = None } when t == t_dynamic -> mono_equals_dynamic
+	| TMono { contents = None }, t when t == t_dynamic -> mono_equals_dynamic
 	| TMono { contents = Some t1 }, TMono { contents = Some t2 } ->
 		fast_eq_anon t1 t2
 	| TAnon a1, TAnon a2 ->

+ 8 - 4
src/typing/typer.ml

@@ -107,7 +107,7 @@ let maybe_type_against_enum ctx f with_type iscall p =
 				| TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) ->
 					begin match get_abstract_froms a pl with
 						| [t2] ->
-							if (List.exists (fast_eq_anon t) stack) then raise Exit;
+							if (List.exists (fast_eq_anon ~mono_equals_dynamic:true t) stack) then raise Exit;
 							loop (t :: stack) t2
 						| _ -> raise Exit
 					end
@@ -1610,8 +1610,12 @@ and type_object_decl ctx fl with_type p =
 		let rec loop seen t =
 			match follow t with
 			| TAnon a -> ODKWithStructure a
-			| TAbstract (a,pl) as t when not (Meta.has Meta.CoreType a.a_meta) && not (List.exists (fun t' -> fast_eq_anon t t') seen) ->
-				(match List.fold_left (fun acc t' -> match loop (t :: seen) t' with ODKPlain -> acc | t -> t :: acc) [] (get_abstract_froms a pl) with
+			| TAbstract (a,pl) as t
+				when not (Meta.has Meta.CoreType a.a_meta)
+					&& not (List.exists (fun t' -> fast_eq_anon ~mono_equals_dynamic:true t t') seen) ->
+				let froms = get_abstract_froms a pl
+				and fold = fun acc t' -> match loop (t :: seen) t' with ODKPlain -> acc | t -> t :: acc in
+				(match List.fold_left fold [] froms with
 				| [t] -> t
 				| _ -> ODKPlain)
 			| TDynamic t when (follow t != t_dynamic) ->
@@ -2096,7 +2100,7 @@ and type_array_decl ctx el with_type p =
 					Some (get_iterable_param t)
 				with Not_found ->
 					None)
-			| TAbstract (a,pl) as t when not (List.exists (fun t' -> fast_eq_anon t (follow t')) seen) ->
+			| TAbstract (a,pl) as t when not (List.exists (fun t' -> fast_eq_anon ~mono_equals_dynamic:true t (follow t')) seen) ->
 				let types =
 					List.fold_left
 						(fun acc t' -> match loop (t :: seen) t' with

+ 9 - 0
tests/misc/compiler_loops/projects/Issue8588/Main5.hx

@@ -0,0 +1,9 @@
+abstract Under<T>(T) {
+	@:from public static function from<T>(v:Under<T>) { return v; }
+}
+
+ class Main5 {
+	static public function main() {
+		var a1:Under<Dynamic> = {};
+	}
+}

+ 1 - 0
tests/misc/compiler_loops/projects/Issue8588/compile5-fail.hxml

@@ -0,0 +1 @@
+-main Main5

+ 1 - 0
tests/misc/compiler_loops/projects/Issue8588/compile5-fail.hxml.stderr

@@ -0,0 +1 @@
+Main5.hx:7: characters 3-30 : { } should be Under<Dynamic>