Browse Source

[typer] don't consider abstract for top-down inference if they have no from casts

see #10730
Simon Krajewski 3 years ago
parent
commit
a49b191c9b
2 changed files with 30 additions and 5 deletions
  1. 12 5
      src/typing/typer.ml
  2. 18 0
      tests/unit/src/unit/issues/Issue10730.hx

+ 12 - 5
src/typing/typer.ml

@@ -781,11 +781,18 @@ and type_object_decl ctx fl with_type p =
 			| TAbstract (a,pl) as t
 				when not (Meta.has Meta.CoreType a.a_meta)
 					&& not (List.exists (fun t' -> shallow_eq t t') seen) ->
-				let froms = get_abstract_froms ctx 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
-				| _ -> ODKFailed)
+				let froms = get_abstract_froms ctx a pl in
+				begin match froms with
+				| [] ->
+					(* If the abstract has no casts in the first place, we can assume plain typing (issue #10730) *)
+					ODKPlain
+				| _ ->
+					let fold = fun acc t' -> match loop (t :: seen) t' with ODKPlain -> acc | t -> t :: acc in
+					begin match List.fold_left fold [] froms with
+						| [t] -> t
+						| _ -> ODKFailed
+					end
+				end
 			| TDynamic t when (follow t != t_dynamic) ->
 				dynamic_parameter := Some t;
 				ODKWithStructure {

+ 18 - 0
tests/unit/src/unit/issues/Issue10730.hx

@@ -0,0 +1,18 @@
+package unit.issues;
+
+import haxe.extern.EitherType;
+
+private abstract A(String) {}
+private typedef ET = EitherType<DocumentFilter, A>;
+
+private typedef DocumentFilter = {
+	final ?language:String;
+	final ?scheme:String;
+}
+
+class Issue10730 extends Test {
+	function testSimn() {
+		final et:ET = {language: "haxe"};
+		utest.Assert.pass();
+	}
+}