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

[matcher] fix how we deal with type parameter unapplication

closes #7672
Simon Krajewski 6 жил өмнө
parent
commit
19d309efdd

+ 5 - 5
src/typing/matcher.ml

@@ -42,7 +42,9 @@ let type_field_access ctx ?(resume=false) e name =
 	Calls.acc_get ctx (Fields.type_field (Fields.TypeFieldConfig.create resume) ctx e name e.epos MGet) e.epos
 
 let unapply_type_parameters params monos =
-	List.iter2 (fun (_,t1) t2 -> match t2,follow t2 with TMono m1,TMono m2 when m1 == m2 -> Type.unify t1 t2 | _ -> ()) params monos
+	List.iter2 (fun (_,t1) t2 ->
+		match t2,follow t2 with TMono m1,TMono m2 -> m1 := Some t1 | _ -> ()
+	) params monos
 
 let get_general_module_type ctx mt p =
 	let rec loop = function
@@ -320,8 +322,8 @@ module Pattern = struct
 					| TField(_, FEnum(en,ef)),TFun(_,TEnum(_,tl)) ->
 						let monos = List.map (fun _ -> mk_mono()) ef.ef_params in
 						let map t = apply_params en.e_params tl (apply_params ef.ef_params monos t) in
-						(* We cannot use e1.etype here because it has applied type parameters (issue #1310). *)
-						let args = match follow (map ef.ef_type) with
+						unify ctx (map ef.ef_type) e1.etype e1.epos;
+						let args = match follow e1.etype with
 							| TFun(args,r) ->
 								unify_expected r;
 								args
@@ -343,8 +345,6 @@ module Pattern = struct
 								error "Too many arguments" p
 						in
 						let patterns = loop el args in
-						(* We want to change the original monomorphs back to type parameters, but we don't want to do that
-						   if they are bound to other monomorphs (issue #4578). *)
 						unapply_type_parameters ef.ef_params monos;
 						PatConstructor(con_enum en ef e1.epos,patterns)
 					| _ ->

+ 22 - 0
tests/misc/projects/Issue6622/Main1.hx

@@ -0,0 +1,22 @@
+enum FmtOption<A> {
+	FixedPrecision:FmtOption<A>;
+}
+
+enum Fmt<A,B> {
+	Opt<C>(opt:FmtOption<C>):Fmt<A,C>;
+}
+
+class Main {
+	static public function main() {
+	}
+
+	static function eval<A, B>(fmt:Fmt<A, B>, f:String -> A):B {
+		return switch (fmt) {
+			case Opt(FixedPrecision):
+				$type(fmt);
+				var r =f("");
+				$type(f);
+				r;
+		}
+	}
+}

+ 2 - 0
tests/misc/projects/Issue6622/compile1-fail.hxml

@@ -0,0 +1,2 @@
+--main Main1
+--interp

+ 3 - 0
tests/misc/projects/Issue6622/compile1-fail.hxml.stderr

@@ -0,0 +1,3 @@
+Main1.hx:16: characters 11-14 : Warning : Fmt<eval.A, eval.B>
+Main1.hx:18: characters 11-12 : Warning : String -> eval.A
+Main1.hx:15: lines 15-19 : eval.A should be eval.B

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

@@ -0,0 +1,32 @@
+package unit.issues;
+
+private enum EListingField<T:Obj> {
+	ELCounter;
+	ELID;
+}
+
+private typedef TListingConf<T:Obj> = {
+	fields:Array<EListingField<T>>
+}
+
+private class Obj {
+	public var id : Int;
+}
+
+class Issue7672 extends unit.Test {
+	function test() {
+		doesnt({ fields: [ELID] }, [null]);
+	}
+
+	function doesnt<T:Obj>( conf : TListingConf<T>, iterable : Iterable<T> )
+		for (o in iterable)
+			for (field in conf.fields) {
+				switch field {
+					case ELCounter:
+						'<td>&nbsp;</td>';
+					case ELID:
+						HelperMacros.typedAs((null : T), o);
+						'<td>${o.id}</td>';
+				}
+			}
+}