Browse Source

[typer] bring back check_param_constraint

closes #9560
Simon Krajewski 5 years ago
parent
commit
3d935b333a
3 changed files with 46 additions and 7 deletions
  1. 31 6
      src/typing/typeload.ml
  2. 1 1
      src/typing/typeloadFields.ml
  3. 14 0
      tests/unit/src/unit/issues/Issue9560.hx

+ 31 - 6
src/typing/typeload.ml

@@ -277,6 +277,29 @@ let make_extension_type ctx tl =
 	let ta = mk_anon ~fields (ref (Extend tl)) in
 	let ta = mk_anon ~fields (ref (Extend tl)) in
 	ta
 	ta
 
 
+let check_param_constraints ctx t map c p =
+	match follow t with
+	| TMono _ -> ()
+	| _ ->
+		let ctl = (match c.cl_kind with KTypeParameter l -> l | _ -> []) in
+		List.iter (fun ti ->
+			let ti = map ti in
+			try
+				unify_raise ctx t ti p
+			with Error(Unify l,p) ->
+				let fail() =
+					if not ctx.untyped then display_error ctx (error_msg (Unify (Constraint_failure (s_type_path c.cl_path) :: l))) p;
+				in
+				match follow t with
+				| TInst({cl_kind = KExpr e},_) ->
+					let e = type_expr {ctx with locals = PMap.empty} e (WithType.with_type ti) in
+					begin try unify_raise ctx e.etype ti p
+					with Error (Unify _,_) -> fail() end
+				| _ ->
+					fail()
+
+		) ctl
+
 (* build an instance from a full type *)
 (* build an instance from a full type *)
 let rec load_instance' ctx (t,p) allow_no_params =
 let rec load_instance' ctx (t,p) allow_no_params =
 	let t = try
 	let t = try
@@ -335,6 +358,7 @@ let rec load_instance' ctx (t,p) allow_no_params =
 					TInst (c,[])
 					TInst (c,[])
 				| TPType t -> load_complex_type ctx true t
 				| TPType t -> load_complex_type ctx true t
 			in
 			in
+			let checks = DynArray.create () in
 			let rec loop tl1 tl2 is_rest = match tl1,tl2 with
 			let rec loop tl1 tl2 is_rest = match tl1,tl2 with
 				| t :: tl1,(name,t2) :: tl2 ->
 				| t :: tl1,(name,t2) :: tl2 ->
 					let t = load_param t in
 					let t = load_param t in
@@ -350,8 +374,12 @@ let rec load_instance' ctx (t,p) allow_no_params =
 					in
 					in
 					let is_rest = is_rest || name = "Rest" && is_generic_build in
 					let is_rest = is_rest || name = "Rest" && is_generic_build in
 					let t = match follow t2 with
 					let t = match follow t2 with
+						| TInst ({ cl_kind = KTypeParameter [] } as c, []) when not is_generic ->
+							check_const c;
+							t
 						| TInst (c,[]) ->
 						| TInst (c,[]) ->
 							check_const c;
 							check_const c;
+							DynArray.add checks (t,c);
 							t
 							t
 						| _ -> die "" __LOC__
 						| _ -> die "" __LOC__
 					in
 					in
@@ -389,12 +417,9 @@ let rec load_instance' ctx (t,p) allow_no_params =
 					) in
 					) in
 					t
 					t
 				in
 				in
-				delay ctx PCheckConstraint (fun () ->
-					try
-						Monomorph.check_constraints map types params;
-					with Unify_error l ->
-						raise_error (Unify l) p
-				);
+				DynArray.iter (fun (t,c) ->
+					check_param_constraints ctx t map c p
+				) checks
 			end;
 			end;
 			f params
 			f params
 		end
 		end

+ 1 - 1
src/typing/typeloadFields.ml

@@ -905,7 +905,7 @@ let check_abstract (ctx,cctx,fctx) c cf fd t ret p =
 	match cctx.abstract with
 	match cctx.abstract with
 		| Some a ->
 		| Some a ->
 			let m = mk_mono() in
 			let m = mk_mono() in
-			let ta = TAbstract(a,Monomorph.spawn_constrained_monos (fun t -> t) a.a_params) in
+			let ta = TAbstract(a,List.map (fun _ -> mk_mono()) a.a_params) in
 			let tthis = if fctx.is_abstract_member || Meta.has Meta.To cf.cf_meta then monomorphs a.a_params a.a_this else a.a_this in
 			let tthis = if fctx.is_abstract_member || Meta.has Meta.To cf.cf_meta then monomorphs a.a_params a.a_this else a.a_this in
 			let allows_no_expr = ref (Meta.has Meta.CoreType a.a_meta) in
 			let allows_no_expr = ref (Meta.has Meta.CoreType a.a_meta) in
 			let rec loop ml =
 			let rec loop ml =

+ 14 - 0
tests/unit/src/unit/issues/Issue9560.hx

@@ -0,0 +1,14 @@
+package unit.issues;
+
+import haxe.Constraints.Function;
+
+class Issue9560 extends unit.Test {
+	public function test() {
+		var t:ERegAbs<Int->Int, ~/foo/i> = a -> a + a;
+		utest.Assert.pass();
+	}
+}
+
+private abstract ERegAbs<T:Function, @:const R:EReg>(T) {
+    @:from private static function fromFunction<T:Function>(v:T):ERegAbs<T, ~//> return cast v;
+}