فهرست منبع

only register constraints check if call unification was successful (might avoid some overload issues later)

Simon Krajewski 13 سال پیش
والد
کامیت
8548fd261d
3فایلهای تغییر یافته به همراه24 افزوده شده و 17 حذف شده
  1. 3 0
      tests/unit/MyClass.hx
  2. 6 1
      tests/unit/TestType.hx
  3. 15 16
      typer.ml

+ 3 - 0
tests/unit/MyClass.hx

@@ -134,4 +134,7 @@ class ParamConstraintsClass {
 	public function memberMultiple < A:(Base, I1) > (a:A):A { return a; }
 	public function memberComplex < A:I1, B:List<A> > (a:A, b:B) { return b; }
 	public function memberBasic < A:String, B:Array<A> > (a:A, b:B) { return b[0]; }
+	
+	@:overload(function< A, B:Array<A> > (a:A, b:B):Void { } )
+	public function memberOverload<A,B>(a:String, b:String) { }
 }

+ 6 - 1
tests/unit/TestType.hx

@@ -429,6 +429,11 @@ class TestType extends Test {
 		//typeError(pcc.memberComplex(ci1, [ci1]));
 		
 		eq(pcc.memberBasic("foo", ["bar"]), "bar");
-		//eq(pcc.memberBasic("foo", ["bar"]), "foobar");
+		
+		pcc.memberOverload("foo", "bar");
+		pcc.memberOverload(1, [2]);
+		// TODO: this should fail
+		pcc.memberOverload(1, ["foo"]);
+		
 	}
 }

+ 15 - 16
typer.ml

@@ -278,24 +278,24 @@ let rec unify_call_params ctx cf el args r p inline =
 		else
 			(null (ctx.t.tnull t) p, true)
 	in
-	let tout = TFun(args,r) in
-	let tout = match cf with
-	| Some cf when cf.cf_params <> [] ->
-		let params = ref [] in
-		params := List.map (fun (n,t) ->
-			match follow t with
-			| TInst(c,[]) ->
-				let t = mk_mono() in
-				delay_late ctx (fun () -> Typeload.check_param_constraints ctx cf.cf_params t (!params) c p);
-				t
-			| _ -> assert false
-		) cf.cf_params;
-		apply_params cf.cf_params !params tout 
-	| _ -> tout in
+	let tout,delays = match cf with
+		| Some cf when cf.cf_params <> [] ->
+			let pl = ref [] in
+			let delays = List.fold_left (fun delays (n,t) ->
+				match follow t with
+				| TInst(c,[]) ->
+					let t = mk_mono() in
+					pl := t :: !pl;
+					(fun () -> Typeload.check_param_constraints ctx cf.cf_params t (!pl) c p) :: delays
+				| _ -> assert false) [] (List.rev cf.cf_params)
+			in
+			apply_params cf.cf_params !pl (TFun(args,r)),delays
+		| _ -> TFun(args,r),[] in
 	let args,r = match tout with TFun(args,r) -> args,r | _ -> assert false in
 	let rec loop acc l l2 skip =
 		match l , l2 with
 		| [] , [] ->
+			List.iter (delay_late ctx) delays;
 			if not (inline && ctx.g.doinline) && (match ctx.com.platform with Flash8 | Flash | Js -> true | _ -> false) then
 				List.rev (no_opt acc), tout
 			else
@@ -709,8 +709,7 @@ let rec type_field ctx e i p mode =
 		AKExpr (mk (TField (e,i)) (mk_mono()) p)
 	in
 	(* we do not want to monofy the field in call context immediately to support parameter constraints *)
-	let class_field = match mode with MGet | MSet -> class_field | MCall -> raw_class_field (fun f -> f.cf_type) in
-	let field_type = match mode with MGet | MSet -> field_type | MCall -> fun f -> f.cf_type in
+	let class_field,field_type = match mode with MGet | MSet -> class_field,field_type | MCall -> raw_class_field (fun f -> f.cf_type),fun f -> f.cf_type in
 	match follow e.etype with
 	| TInst (c,params) ->
 		let rec loop_dyn c params =