2
0
Эх сурвалжийг харах

map all the things for GADT (closes #5064)

Simon Krajewski 9 жил өмнө
parent
commit
f295296692

+ 13 - 5
src/typing/matcher.ml

@@ -437,21 +437,29 @@ module Case = struct
 			v.v_type <- map v.v_type;
 			v.v_type <- map v.v_type;
 			(v,t_old) :: acc
 			(v,t_old) :: acc
 		) ctx.locals [] in
 		) ctx.locals [] in
+		let old_ret = ctx.ret in
+		ctx.ret <- map ctx.ret;
 		let pat = Pattern.make ctx (map t) e in
 		let pat = Pattern.make ctx (map t) e in
 		unapply_type_parameters ctx.type_params monos;
 		unapply_type_parameters ctx.type_params monos;
 		let eg = match eg with
 		let eg = match eg with
 			| None -> None
 			| None -> None
 			| Some e -> Some (type_expr ctx e Value)
 			| Some e -> Some (type_expr ctx e Value)
 		in
 		in
-		let eo = match eo with
-			| None ->
-				(match with_type with WithType t -> unify ctx ctx.t.tvoid t (pos e) | _ -> ());
+		let eo = match eo,with_type with
+			| None,WithType t ->
+				unify ctx ctx.t.tvoid t (pos e);
 				None
 				None
-			| Some e ->
+			| None,_ ->
+				None
+			| Some e,WithType t ->
+				let e = type_expr ctx e (WithType (map t)) in
+				let e = Codegen.AbstractCast.cast_or_unify ctx (map t) e e.epos in
+				Some e
+			| Some e,_ ->
 				let e = type_expr ctx e with_type in
 				let e = type_expr ctx e with_type in
-				let e = match with_type with WithType t -> Codegen.AbstractCast.cast_or_unify ctx (map t) e e.epos | _ -> e in
 				Some e
 				Some e
 		in
 		in
+		ctx.ret <- old_ret;
 		List.iter (fun (v,t) -> v.v_type <- t) old_types;
 		List.iter (fun (v,t) -> v.v_type <- t) old_types;
 		save();
 		save();
 		{
 		{

+ 24 - 0
tests/unit/src/unit/issues/Issue5064.hx

@@ -0,0 +1,24 @@
+package unit.issues;
+
+import haxe.ds.Option;
+
+private enum GADT<A> {
+	AnInt(p: Bool): GADT<Int>;
+	AString(p: Bool): GADT<String>;
+}
+
+class Issue5064 extends Test {
+	public static function broken<A>(gadt: GADT<A>): Option<A> {
+		return switch gadt {
+			case AnInt(p): if (p) Some(1) else None;
+			case AString(p): if (p) Some("a") else None;
+		};
+	}
+
+	function test() {
+		t(Type.enumEq(Some(1), broken(AnInt(true))));
+		t(None == broken(AnInt(false)));
+		t(Type.enumEq(Some("a"), broken(AString(true))));
+		t(None == broken(AString(false)));
+	}
+}