Browse Source

only use top-down inference for EFunction if the return type is not unknown (closes #3513)

Simon Krajewski 10 years ago
parent
commit
7f220cbd61
2 changed files with 36 additions and 3 deletions
  1. 32 0
      tests/unit/src/unit/issues/Issue3513.hx
  2. 4 3
      typer.ml

+ 32 - 0
tests/unit/src/unit/issues/Issue3513.hx

@@ -0,0 +1,32 @@
+package unit.issues;
+
+private enum Either<L, R> {
+    Left(l:L);
+    Right(r:R);
+}
+
+private abstract LazyGenerator<Data, End>(Void->Either<Data, End>) from Void->Either<Data, End> {
+	public function next():Either<Data, End>
+		return (this)();
+
+	@:from static function infinite<Data, End>(f:Void->Data):LazyGenerator<Data, End>
+		return function () return Left(f());
+}
+
+class Issue3513 extends Test {
+	function test() {
+        var count = 0;
+        function counter() return count++;
+        var gen:LazyGenerator<Int, Int> = counter;
+        var gen:LazyGenerator<Int, Int> = function ():Int return count++;
+		eq(0, getValue(gen.next()));
+		eq(1, getValue(gen.next()));
+	}
+
+	static function getValue(e:Either<Int, Int>) {
+		return switch (e) {
+			case Left(v): v;
+			case Right(v): v;
+		}
+	}
+}

+ 4 - 3
typer.ml

@@ -3336,9 +3336,10 @@ and type_expr ctx (e,p) (with_type:with_type) =
 						| _ -> ()
 					) args args2;
 					(* unify for top-down inference unless we are expecting Void *)
-					begin match follow tr with
-						| TAbstract({a_path = [],"Void"},_) -> ()
-						| _ -> unify ctx rt tr p
+					begin match follow tr,follow rt with
+						| TAbstract({a_path = [],"Void"},_),_ -> ()
+						| _,TMono _ -> unify ctx rt tr p
+						| _ -> ()
 					end
 				| TAbstract(a,tl) ->
 					loop (Abstract.get_underlying_type a tl)