Selaa lähdekoodia

fix single pattern match for abstracted enum (#9592)

Dmitrii Maganov 5 vuotta sitten
vanhempi
commit
1bf5d59d2a
3 muutettua tiedostoa jossa 37 lisäystä ja 5 poistoa
  1. 7 1
      src/core/abstract.ml
  2. 10 4
      src/typing/typer.ml
  3. 20 0
      tests/unit/src/unit/issues/Issue9577.hx

+ 7 - 1
src/core/abstract.ml

@@ -110,4 +110,10 @@ let rec follow_with_abstracts_without_null t = match follow_without_null t with
 	| TAbstract(a,tl) when not (Meta.has Meta.CoreType a.a_meta) ->
 		follow_with_abstracts_without_null (get_underlying_type a tl)
 	| t ->
-		t
+		t
+
+let rec follow_with_abstracts_forward t = match follow t with
+	| TAbstract(a,tl) when (Meta.has Meta.Forward a.a_meta) && not (Meta.has Meta.CoreType a.a_meta) ->
+		follow_with_abstracts_forward (get_underlying_type ~return_first:true a tl)
+	| t ->
+		t

+ 10 - 4
src/typing/typer.ml

@@ -2439,10 +2439,16 @@ and type_call ?(mode=MGet) ctx e el (with_type:WithType.t) inline p =
 		e
 	| (EField(e,"match"),p), [epat] ->
 		let et = type_expr ctx e WithType.value in
-		(match follow et.etype with
-			| TEnum _ ->
-				Matcher.Match.match_expr ctx e [[epat],None,Some (EConst(Ident "true"),p),p] (Some (Some (EConst(Ident "false"),p),p)) (WithType.with_type ctx.t.tbool) true p
-			| _ -> def ())
+		let is_enum_match = match follow et.etype with
+			| TEnum _ -> true
+			| TAbstract _ as t when (match Abstract.follow_with_abstracts_forward t with TEnum _ -> true | _ -> false) ->
+				(try ignore (type_field (TypeFieldConfig.create true) ctx et "match" p mode); false with _ -> true)
+			| _ -> false
+		in
+		if is_enum_match then
+			Matcher.Match.match_expr ctx e [[epat],None,Some (EConst(Ident "true"),p),p] (Some (Some (EConst(Ident "false"),p),p)) (WithType.with_type ctx.t.tbool) true p
+		else
+			def ()
 	| (EConst (Ident "__unprotect__"),_) , [(EConst (String _),_) as e] ->
 		let e = type_expr ctx e WithType.value in
 		if Common.platform ctx.com Flash then

+ 20 - 0
tests/unit/src/unit/issues/Issue9577.hx

@@ -0,0 +1,20 @@
+package unit.issues;
+
+import haxe.ds.Option;
+
+class Issue9577 extends Test {
+  function test() {
+    var foo: Foo = Some(9577);
+    var bar: Bar = Some(9577);
+    eq(true, foo.match(Some(9577)));
+    eq(9578, bar.match(9577));
+  }
+}
+
+@:forward private abstract Foo(Option<Int>) from Option<Int> {}
+
+@:forward private abstract Bar(Option<Int>) from Option<Int> {
+  public function match(value: Int) {
+    return value + 1;
+  }
+}