Browse Source

[typer] fix stack overflow when typing arrays against abstracts

closes #6059
Simon Krajewski 7 years ago
parent
commit
0dcb3231d3

+ 4 - 4
src/typing/typer.ml

@@ -2062,7 +2062,7 @@ and type_local_function ctx name f with_type p =
 and type_array_decl ctx el with_type p =
 	let tp = (match with_type with
 	| WithType t ->
-		let rec loop t =
+		let rec loop seen t =
 			(match follow t with
 			| TInst ({ cl_path = [],"Array" },[tp]) ->
 				(match follow tp with
@@ -2073,14 +2073,14 @@ and type_array_decl ctx el with_type p =
 					Some (get_iterable_param t)
 				with Not_found ->
 					None)
-			| TAbstract (a,pl) ->
-				(match List.fold_left (fun acc t -> match loop t with None -> acc | Some t -> t :: acc) [] (get_abstract_froms a pl) with
+			| TAbstract (a,pl) as t when not (List.exists (fun t' -> fast_eq t t') seen) ->
+				(match List.fold_left (fun acc t -> match loop (t :: seen) t with None -> acc | Some t -> t :: acc) [] (get_abstract_froms a pl) with
 				| [t] -> Some t
 				| _ -> None)
 			| t ->
 				if t == t_dynamic then Some t else None)
 		in
-		loop t
+		loop [] t
 	| _ ->
 		None
 	) in

+ 36 - 0
tests/unit/src/unit/issues/Issue6059.hx

@@ -0,0 +1,36 @@
+package unit.issues;
+
+class Issue6059 extends Test {
+#if !as3 // See #6891
+	public static inline function foo (name : B, ?id : B, data : Array<String>) : Void { }
+
+	public static function test () : Void {
+		Issue6059.foo ("", []); // -> stackoverflow
+		Issue6059.foo ("", null, []); // ok
+	}
+#end
+}
+
+private abstract A (String) {
+	public inline function new (value : String) {
+		this = value;
+	}
+	@:from
+		public static function fromB (value : B) : A {
+			return new A (Std.string (value));
+		}
+}
+
+private abstract B (String) {
+	public inline function new (value : String) {
+		this = value;
+	}
+	@:from
+		public static function fromString (value : String) : B {
+			return new B (value);
+		}
+	@:from
+		public static function fromA (value : A) : B  {
+			return new B (Std.string (value));
+		}
+}

+ 1 - 1
tests/unit/src/unit/issues/Issue6952.hx

@@ -3,7 +3,7 @@ package unit.issues;
 @:generic class Issue6952TestClass<@:const T> {
 	public function new() {}
 	public function foo() {
-		trace(T);
+		return T;
 	}
 }