浏览代码

fix top-down inference infinite recursion issue (closes #5848)

Simon Krajewski 8 年之前
父节点
当前提交
d37739386e
共有 3 个文件被更改,包括 52 次插入4 次删除
  1. 6 0
      extra/CHANGES.txt
  2. 6 4
      src/typing/typer.ml
  3. 40 0
      tests/unit/src/unit/issues/Issue5848.hx

+ 6 - 0
extra/CHANGES.txt

@@ -1,3 +1,9 @@
+2016-??-??: 3.4.0-RC2
+
+	Bugfixes:
+
+	all : fixed top-down inference infinite recursion issue (#5848)
+
 2016-11-29: 3.4.0-RC1
 
 	New features:

+ 6 - 4
src/typing/typer.ml

@@ -4012,23 +4012,25 @@ and maybe_type_against_enum ctx f with_type p =
 	try
 		begin match with_type with
 		| WithType t ->
-			let rec loop t = match follow t with
+			let rec loop stack t = match follow t with
 				| TEnum (en,_) ->
 					en.e_path,en.e_names,TEnumDecl en
 				| TAbstract ({a_impl = Some c} as a,_) when has_meta Meta.Enum a.a_meta ->
 					a.a_path,List.map (fun cf -> cf.cf_name) c.cl_ordered_fields,TAbstractDecl a
 				| TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) ->
 					begin match get_abstract_froms a pl with
-						| [t] -> loop t
+						| [t2] ->
+							if (List.exists (fast_eq t) stack) then raise Exit;
+							loop (t :: stack) t2
 						| _ -> raise Exit
 					end
 				(* We might type against an enum constructor. *)
 				| TFun(_,tr) ->
-					loop tr
+					loop stack tr
 				| _ ->
 					raise Exit
 			in
-			let path,fields,mt = loop t in
+			let path,fields,mt = loop [] t in
 			let old = ctx.m.curmod.m_types in
 			let restore () = ctx.m.curmod.m_types <- old in
 			ctx.m.curmod.m_types <- ctx.m.curmod.m_types @ [mt];

+ 40 - 0
tests/unit/src/unit/issues/Issue5848.hx

@@ -0,0 +1,40 @@
+package unit.issues;
+
+private abstract Degree(Float) {
+	public inline function new (f:Float) {
+		this = f;
+	}
+	@:from // removing this line makes it compile
+	public static function fromRadian (d:Radian):Degree {
+		return new Degree(d.float());
+	}
+	public inline function float ():Float return this;
+}
+
+private abstract Radian(Float) {
+	public inline function new (f:Float) {
+		this = f;
+	}
+
+	@:from static inline function fromDegree (d:Degree):Radian {
+		return new Radian(d.float());
+	}
+
+	public inline function float ():Float return this;
+}
+
+private class Vec2s {
+	public static function foo (radian:Radian) {
+		return 1;
+	}
+}
+
+class Issue5848 extends unit.Test {
+	function test():Void {
+		ff(new Degree(90));
+	}
+
+	static public function ff(r:Radian) {
+		Vec2s.foo(r);
+	}
+}