Bläddra i källkod

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

Simon Krajewski 13 år sedan
förälder
incheckning
8548fd261d
3 ändrade filer med 24 tillägg och 17 borttagningar
  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 =