浏览代码

Merge pull request #3319 from Simn/refactor_2014

Rewrite `unify_call_args`
Simon Krajewski 11 年之前
父节点
当前提交
5796744a86
共有 16 个文件被更改,包括 306 次插入314 次删除
  1. 13 12
      codegen.ml
  2. 1 1
      dce.ml
  3. 1 1
      filters.ml
  4. 2 2
      genas3.ml
  5. 20 20
      gencommon.ml
  6. 10 10
      gencpp.ml
  7. 14 14
      gencs.ml
  8. 3 3
      genjava.ml
  9. 5 5
      genpy.ml
  10. 1 1
      genswf9.ml
  11. 4 2
      interp.ml
  12. 5 5
      optimizer.ml
  13. 18 17
      type.ml
  14. 15 1
      typecore.ml
  15. 5 5
      typeload.ml
  16. 189 215
      typer.ml

+ 13 - 12
codegen.ml

@@ -267,7 +267,7 @@ let generic_substitute_expr gctx e =
 	in
 	in
 	let rec build_expr e =
 	let rec build_expr e =
 		match e.eexpr with
 		match e.eexpr with
-		| TField(e1, FInstance({cl_kind = KGeneric},cf)) ->
+		| TField(e1, FInstance({cl_kind = KGeneric},_,cf)) ->
 			build_expr {e with eexpr = TField(e1,quick_field_dynamic (generic_substitute_type gctx (e1.etype)) cf.cf_name)}
 			build_expr {e with eexpr = TField(e1,quick_field_dynamic (generic_substitute_type gctx (e1.etype)) cf.cf_name)}
 		| _ -> map_expr_type build_expr (generic_substitute_type gctx) build_var e
 		| _ -> map_expr_type build_expr (generic_substitute_type gctx) build_var e
 	in
 	in
@@ -909,7 +909,7 @@ let detect_usage com =
 					let p = {e.epos with pmin = e.epos.pmax - (String.length ef.ef_name)} in
 					let p = {e.epos with pmin = e.epos.pmax - (String.length ef.ef_name)} in
 					usage := p :: !usage;
 					usage := p :: !usage;
 					Type.iter expr e
 					Type.iter expr e
-				| TField(_,(FAnon cf | FInstance (_,cf) | FStatic (_,cf) | FClosure (_,cf))) when Meta.has Meta.Usage cf.cf_meta ->
+				| TField(_,(FAnon cf | FInstance (_,_,cf) | FStatic (_,cf) | FClosure (_,cf))) when Meta.has Meta.Usage cf.cf_meta ->
 					let p = {e.epos with pmin = e.epos.pmax - (String.length cf.cf_name)} in
 					let p = {e.epos with pmin = e.epos.pmax - (String.length cf.cf_name)} in
 					usage := p :: !usage;
 					usage := p :: !usage;
 					Type.iter expr e
 					Type.iter expr e
@@ -1503,15 +1503,15 @@ struct
 
 
 	let rec rm_duplicates acc ret = match ret with
 	let rec rm_duplicates acc ret = match ret with
 		| [] -> acc
 		| [] -> acc
-		| ( el, t ) :: ret when List.exists (fun (_,t2) -> type_iseq t t2) acc ->
+		| ( el, t, _ ) :: ret when List.exists (fun (_,t2,_) -> type_iseq t t2) acc ->
 			rm_duplicates acc ret
 			rm_duplicates acc ret
 		| r :: ret ->
 		| r :: ret ->
 			rm_duplicates (r :: acc) ret
 			rm_duplicates (r :: acc) ret
 
 
-	let s_options rated =
+(* 	let s_options rated =
 		String.concat ",\n" (List.map (fun ((_,t),rate) ->
 		String.concat ",\n" (List.map (fun ((_,t),rate) ->
 			"( " ^ (String.concat "," (List.map (fun (i,i2) -> string_of_int i ^ ":" ^ string_of_int i2) rate)) ^ " ) => " ^ (s_type (print_context()) t)
 			"( " ^ (String.concat "," (List.map (fun (i,i2) -> string_of_int i ^ ":" ^ string_of_int i2) rate)) ^ " ) => " ^ (s_type (print_context()) t)
-		) rated)
+		) rated) *)
 
 
 	let count_optionals elist =
 	let count_optionals elist =
 		List.fold_left (fun acc (_,is_optional) -> if is_optional then acc + 1 else acc) 0 elist
 		List.fold_left (fun acc (_,is_optional) -> if is_optional then acc + 1 else acc) 0 elist
@@ -1519,7 +1519,7 @@ struct
 	let rec fewer_optionals acc compatible = match acc, compatible with
 	let rec fewer_optionals acc compatible = match acc, compatible with
 		| _, [] -> acc
 		| _, [] -> acc
 		| [], c :: comp -> fewer_optionals [c] comp
 		| [], c :: comp -> fewer_optionals [c] comp
-		| (elist_acc, _) :: _, ((elist, _) as cur) :: comp ->
+		| (elist_acc, _, _) :: _, ((elist, _, _) as cur) :: comp ->
 			let acc_opt = count_optionals elist_acc in
 			let acc_opt = count_optionals elist_acc in
 			let comp_opt = count_optionals elist in
 			let comp_opt = count_optionals elist in
 			if acc_opt = comp_opt then
 			if acc_opt = comp_opt then
@@ -1530,7 +1530,8 @@ struct
 				fewer_optionals [cur] comp
 				fewer_optionals [cur] comp
 
 
 	let reduce_compatible compatible = match fewer_optionals [] (rm_duplicates [] compatible) with
 	let reduce_compatible compatible = match fewer_optionals [] (rm_duplicates [] compatible) with
-		| [] -> [] | [v] -> [v]
+		| [] -> []
+		| [v] -> [v]
 		| compatible ->
 		| compatible ->
 			(* convert compatible into ( rate * compatible_type ) list *)
 			(* convert compatible into ( rate * compatible_type ) list *)
 			let rec mk_rate acc elist args = match elist, args with
 			let rec mk_rate acc elist args = match elist, args with
@@ -1543,8 +1544,8 @@ struct
 
 
 			let rated = ref [] in
 			let rated = ref [] in
 			List.iter (function
 			List.iter (function
-				| (elist,TFun(args,ret)) -> (try
-					rated := ( (elist,TFun(args,ret)), mk_rate [] elist args ) :: !rated
+				| (elist,TFun(args,ret),d) -> (try
+					rated := ( (elist,TFun(args,ret),d), mk_rate [] elist args ) :: !rated
 					with | Not_found -> ())
 					with | Not_found -> ())
 				| _ -> assert false
 				| _ -> assert false
 			) compatible;
 			) compatible;
@@ -1561,10 +1562,10 @@ struct
 						loop ( (rover,rargs) :: best ) rem
 						loop ( (rover,rargs) :: best ) rem
 			in
 			in
 
 
-			List.map fst (loop [] !rated)
+			let r = loop [] !rated in
+			List.map fst r
 end;;
 end;;
 
 
-
 module UnificationCallback = struct
 module UnificationCallback = struct
 	let tf_stack = ref []
 	let tf_stack = ref []
 
 
@@ -1691,7 +1692,7 @@ module DeprecationCheck = struct
 			| TField(e1,fa) ->
 			| TField(e1,fa) ->
 				expr e1;
 				expr e1;
 				begin match fa with
 				begin match fa with
-					| FStatic(c,cf) | FInstance(c,cf) ->
+					| FStatic(c,cf) | FInstance(c,_,cf) ->
 						check_class com c e.epos;
 						check_class com c e.epos;
 						check_cf com cf e.epos
 						check_cf com cf e.epos
 					| FAnon cf ->
 					| FAnon cf ->

+ 1 - 1
dce.ml

@@ -352,7 +352,7 @@ and expr dce e =
 			| FStatic(c,cf) ->
 			| FStatic(c,cf) ->
 				mark_class dce c;
 				mark_class dce c;
 				mark_field dce c cf true;
 				mark_field dce c cf true;
-			| FInstance(c,cf) ->
+			| FInstance(c,_,cf) ->
 				mark_class dce c;
 				mark_class dce c;
 				mark_field dce c cf false;
 				mark_field dce c cf false;
 			| _ ->
 			| _ ->

+ 1 - 1
filters.ml

@@ -1034,7 +1034,7 @@ let add_field_inits ctx t =
 				match cf.cf_expr with
 				match cf.cf_expr with
 				| None -> assert false
 				| None -> assert false
 				| Some e ->
 				| Some e ->
-					let lhs = mk (TField(ethis,FInstance (c,cf))) cf.cf_type e.epos in
+					let lhs = mk (TField(ethis,FInstance (c,List.map snd c.cl_params,cf))) cf.cf_type e.epos in
 					cf.cf_expr <- None;
 					cf.cf_expr <- None;
 					let eassign = mk (TBinop(OpAssign,lhs,e)) e.etype e.epos in
 					let eassign = mk (TBinop(OpAssign,lhs,e)) e.etype e.epos in
 					if is_as3 then begin
 					if is_as3 then begin

+ 2 - 2
genas3.ml

@@ -47,7 +47,7 @@ type context = {
 
 
 let is_var_field f =
 let is_var_field f =
 	match f with
 	match f with
-	| FStatic (_,f) | FInstance (_,f) ->
+	| FStatic (_,f) | FInstance (_,_,f) ->
 		(match f.cf_kind with Var _ -> true | _ -> false)
 		(match f.cf_kind with Var _ -> true | _ -> false)
 	| _ ->
 	| _ ->
 		false
 		false
@@ -592,7 +592,7 @@ and gen_expr ctx e =
 		print ctx " %s " (Ast.s_binop op);
 		print ctx " %s " (Ast.s_binop op);
 		gen_value_op ctx e2;
 		gen_value_op ctx e2;
 	(* variable fields on interfaces are generated as (class["field"] as class) *)
 	(* variable fields on interfaces are generated as (class["field"] as class) *)
-	| TField ({etype = TInst({cl_interface = true} as c,_)} as ei,FInstance (_,{ cf_name = s }))
+	| TField ({etype = TInst({cl_interface = true} as c,_)} as ei,FInstance (_,_,{ cf_name = s }))
 		when (try (match (PMap.find s c.cl_fields).cf_kind with Var _ -> true | _ -> false) with Not_found -> false) ->
 		when (try (match (PMap.find s c.cl_fields).cf_kind with Var _ -> true | _ -> false) with Not_found -> false) ->
 		spr ctx "(";
 		spr ctx "(";
 		gen_value ctx ei;
 		gen_value ctx ei;

+ 20 - 20
gencommon.ml

@@ -1395,7 +1395,7 @@ let field_access gen (t:t) (field:string) : (tfield_access) =
 		| _ -> FNotFound
 		| _ -> FNotFound
 
 
 let field_access_esp gen t field = match field with
 let field_access_esp gen t field = match field with
-	| FStatic(cl,cf) | FInstance(cl,cf) when Meta.has Meta.Extern cf.cf_meta ->
+	| FStatic(cl,cf) | FInstance(cl,_,cf) when Meta.has Meta.Extern cf.cf_meta ->
 		let static = match field with
 		let static = match field with
 			| FStatic _ -> true
 			| FStatic _ -> true
 			| _ -> false
 			| _ -> false
@@ -1410,7 +1410,7 @@ let field_access_esp gen t field = match field with
 let mk_field_access gen expr field pos =
 let mk_field_access gen expr field pos =
 	match field_access gen expr.etype field with
 	match field_access gen expr.etype field with
 		| FClassField(c,p,dc,cf,false,at,_) ->
 		| FClassField(c,p,dc,cf,false,at,_) ->
-				{ eexpr = TField(expr, FInstance(dc,cf)); etype = apply_params c.cl_params p at; epos = pos }
+				{ eexpr = TField(expr, FInstance(dc,p,cf)); etype = apply_params c.cl_params p at; epos = pos }
 		| FClassField(c,p,dc,cf,true,at,_) ->
 		| FClassField(c,p,dc,cf,true,at,_) ->
 				{ eexpr = TField(expr, FStatic(dc,cf)); etype = at; epos = pos }
 				{ eexpr = TField(expr, FStatic(dc,cf)); etype = at; epos = pos }
 		| FAnonField cf ->
 		| FAnonField cf ->
@@ -2055,7 +2055,7 @@ struct
 							| Method(MethDynamic) ->
 							| Method(MethDynamic) ->
 								(match cf.cf_expr, cf.cf_params with
 								(match cf.cf_expr, cf.cf_params with
 									| Some e, [] ->
 									| Some e, [] ->
-										let var = { eexpr = TField({ eexpr = TConst(TThis); epos = cf.cf_pos; etype = TInst(cl, List.map snd cl.cl_params); }, FInstance(cl, cf)); etype = cf.cf_type; epos = cf.cf_pos } in
+										let var = { eexpr = TField({ eexpr = TConst(TThis); epos = cf.cf_pos; etype = TInst(cl, List.map snd cl.cl_params); }, FInstance(cl, List.map snd cl.cl_params, cf)); etype = cf.cf_type; epos = cf.cf_pos } in
 										let ret = ({ eexpr = TBinop(Ast.OpAssign, var, e); etype = cf.cf_type; epos = cf.cf_pos; }) in
 										let ret = ({ eexpr = TBinop(Ast.OpAssign, var, e); etype = cf.cf_type; epos = cf.cf_pos; }) in
 										cf.cf_expr <- None;
 										cf.cf_expr <- None;
 										let is_override = List.memq cf cl.cl_overrides in
 										let is_override = List.memq cf cl.cl_overrides in
@@ -2068,7 +2068,7 @@ struct
 									| Some e, _ ->
 									| Some e, _ ->
 										let params = List.map (fun _ -> t_dynamic) cf.cf_params in
 										let params = List.map (fun _ -> t_dynamic) cf.cf_params in
 										let fn = apply_params cf.cf_params params in
 										let fn = apply_params cf.cf_params params in
-										let var = { eexpr = TField({ eexpr = TConst(TThis); epos = cf.cf_pos; etype = TInst(cl, List.map snd cl.cl_params); }, FInstance(cl, cf)); etype = cf.cf_type; epos = cf.cf_pos } in
+										let var = { eexpr = TField({ eexpr = TConst(TThis); epos = cf.cf_pos; etype = TInst(cl, List.map snd cl.cl_params); }, FInstance(cl, List.map snd cl.cl_params, cf)); etype = cf.cf_type; epos = cf.cf_pos } in
 										let rec change_expr e =
 										let rec change_expr e =
 											Type.map_expr_type (change_expr) fn (fun v -> v.v_type <- fn v.v_type; v) e
 											Type.map_expr_type (change_expr) fn (fun v -> v.v_type <- fn v.v_type; v) e
 										in
 										in
@@ -3170,7 +3170,7 @@ struct
 								eexpr = TConst TThis;
 								eexpr = TConst TThis;
 								etype = TInst(cls, List.map snd cls.cl_params);
 								etype = TInst(cls, List.map snd cls.cl_params);
 								epos = pos;
 								epos = pos;
-							}, FInstance(cls, cf));
+							}, FInstance(cls, List.map snd cls.cl_params, cf));
 							etype = cf.cf_type;
 							etype = cf.cf_type;
 							epos = pos;
 							epos = pos;
 						}, List.map (fun (v,_) -> mk_local v pos) tfunc.tf_args);
 						}, List.map (fun (v,_) -> mk_local v pos) tfunc.tf_args);
@@ -4271,7 +4271,7 @@ struct
 						if not (PMap.mem name cl.cl_fields) then begin
 						if not (PMap.mem name cl.cl_fields) then begin
 							let reverse_params = List.map (apply_params cls.cl_params (List.map snd cparams)) reverse_params in
 							let reverse_params = List.map (apply_params cls.cl_params (List.map snd cparams)) reverse_params in
 							let cfield = mk_class_field name (TFun([], t_dynamic)) false cl.cl_pos (Method MethNormal) cparams in
 							let cfield = mk_class_field name (TFun([], t_dynamic)) false cl.cl_pos (Method MethNormal) cparams in
-							let field = { eexpr = TField(this, FInstance(cl,cast_cfield)); etype = apply_params cast_cfield.cf_params reverse_params cast_cfield.cf_type; epos = p } in
+							let field = { eexpr = TField(this, FInstance(cl,List.map snd cl.cl_params, cast_cfield)); etype = apply_params cast_cfield.cf_params reverse_params cast_cfield.cf_type; epos = p } in
 							let call =
 							let call =
 							{
 							{
 								eexpr = TCall(field, []);
 								eexpr = TCall(field, []);
@@ -4380,10 +4380,10 @@ struct
 				(* this will take all fields that were *)
 				(* this will take all fields that were *)
 				let fields_to_cases fields =
 				let fields_to_cases fields =
 					List.map (fun (cf, t_cl, t_cf) ->
 					List.map (fun (cf, t_cl, t_cf) ->
-						let this_field = { eexpr = TField(this, FInstance(cl, cf)); etype = t_cl; epos = pos } in
+						let this_field = { eexpr = TField(this, FInstance(cl, List.map snd cl.cl_params, cf)); etype = t_cl; epos = pos } in
 						let expr =
 						let expr =
 						{
 						{
-							eexpr = TBinop(OpAssign, { eexpr = TField(local_new_me, FInstance(cl, cf) ); etype = t_cf; epos = pos },
+							eexpr = TBinop(OpAssign, { eexpr = TField(local_new_me, FInstance(cl, List.map snd cl.cl_params, cf) ); etype = t_cf; epos = pos },
 								try (Hashtbl.find gen.gtparam_cast (get_path t_cf)) this_field t_cf with | Not_found -> (* if not found tparam cast, it shouldn't be a valid hxgeneric *) assert false
 								try (Hashtbl.find gen.gtparam_cast (get_path t_cf)) this_field t_cf with | Not_found -> (* if not found tparam cast, it shouldn't be a valid hxgeneric *) assert false
 							);
 							);
 							etype = t_cf;
 							etype = t_cf;
@@ -4476,7 +4476,7 @@ struct
 				let params = List.map snd cparams in
 				let params = List.map snd cparams in
 
 
 				let me = alloc_var "me" me_type in
 				let me = alloc_var "me" me_type in
-				let field = { eexpr = TField(mk_local me p, FInstance(iface,cf)); etype = apply_params cf.cf_params params cf.cf_type; epos = p } in
+				let field = { eexpr = TField(mk_local me p, FInstance(iface, List.map snd iface.cl_params, cf)); etype = apply_params cf.cf_params params cf.cf_type; epos = p } in
 				let call =
 				let call =
 				{
 				{
 					eexpr = TCall(field, []);
 					eexpr = TCall(field, []);
@@ -6065,7 +6065,7 @@ struct
 							cf,declared_t,false
 							cf,declared_t,false
 					| true ->
 					| true ->
 					let (cf, actual_t, error), is_static = match f with
 					let (cf, actual_t, error), is_static = match f with
-						| FInstance(c,cf) | FClosure(Some c,cf) ->
+						| FInstance(c,_,cf) | FClosure(Some c,cf) ->
 							(* get from overloads *)
 							(* get from overloads *)
 							(* FIXME: this is a workaround for issue #1743 . Uncomment this code after it was solved *)
 							(* FIXME: this is a workaround for issue #1743 . Uncomment this code after it was solved *)
 							(* let t, cf = List.find (fun (t,cf2) -> cf == cf2) (Typeload.get_overloads cl (field_name f)) in *)
 							(* let t, cf = List.find (fun (t,cf2) -> cf == cf2) (Typeload.get_overloads cl (field_name f)) in *)
@@ -6100,7 +6100,7 @@ struct
 				in
 				in
 				(* set the real (selected) class field *)
 				(* set the real (selected) class field *)
 				let f = match f with
 				let f = match f with
-					| FInstance(c,_) -> FInstance(c,cf)
+					| FInstance(c,tl,_) -> FInstance(c,tl,cf)
 					| FClosure(c,_) -> FClosure(c,cf)
 					| FClosure(c,_) -> FClosure(c,cf)
 					| FStatic(c,_) -> FStatic(c,cf)
 					| FStatic(c,_) -> FStatic(c,cf)
 					| f -> f
 					| f -> f
@@ -6717,7 +6717,7 @@ struct
 	let call_super ctx fn_args ret_t cf cl this_t pos =
 	let call_super ctx fn_args ret_t cf cl this_t pos =
 		{
 		{
 			eexpr = TCall({
 			eexpr = TCall({
-				eexpr = TField({ eexpr = TConst(TSuper); etype = this_t; epos = pos }, FInstance(cl,cf));
+				eexpr = TField({ eexpr = TConst(TSuper); etype = this_t; epos = pos }, FInstance(cl,List.map snd cl.cl_params,cf));
 				etype = TFun(fun_args fn_args, ret_t);
 				etype = TFun(fun_args fn_args, ret_t);
 				epos = pos;
 				epos = pos;
 			}, List.map (fun (v,_) -> mk_local v pos) fn_args);
 			}, List.map (fun (v,_) -> mk_local v pos) fn_args);
@@ -7477,7 +7477,7 @@ struct
 						fun () ->
 						fun () ->
 							mk_return {
 							mk_return {
 								eexpr = TCall(
 								eexpr = TCall(
-									{ eexpr = TField({ eexpr = TConst TSuper; etype = t; epos = pos }, FInstance(cl, cfield)); etype = !fun_type; epos = pos },
+									{ eexpr = TField({ eexpr = TConst TSuper; etype = t; epos = pos }, FInstance(cl, List.map snd cl.cl_params, cfield)); etype = !fun_type; epos = pos },
 									(List.map (fun (v,_) -> mk_local v pos) args) );
 									(List.map (fun (v,_) -> mk_local v pos) args) );
 								etype = if is_float then basic.tfloat else t_dynamic;
 								etype = if is_float then basic.tfloat else t_dynamic;
 								epos = pos;
 								epos = pos;
@@ -7497,7 +7497,7 @@ struct
 				in
 				in
 
 
 				let do_field cf cf_type is_static =
 				let do_field cf cf_type is_static =
-					let get_field ethis = { eexpr = TField (ethis, if is_static then FStatic (cl, cf) else FInstance(cl, cf)); etype = cf_type; epos = pos } in
+					let get_field ethis = { eexpr = TField (ethis, if is_static then FStatic (cl, cf) else FInstance(cl, List.map snd cl.cl_params, cf)); etype = cf_type; epos = pos } in
 					let this = if is_static then mk_classtype_access cl pos else { eexpr = TConst(TThis); etype = t; epos = pos } in
 					let this = if is_static then mk_classtype_access cl pos else { eexpr = TConst(TThis); etype = t; epos = pos } in
 					let value_local = if is_float then match follow cf_type with
 					let value_local = if is_float then match follow cf_type with
 						| TInst({ cl_kind = KTypeParameter _ }, _) ->
 						| TInst({ cl_kind = KTypeParameter _ }, _) ->
@@ -7585,13 +7585,13 @@ struct
 								eexpr = TIf(
 								eexpr = TIf(
 									handle_prop_local,
 									handle_prop_local,
 									mk_return (mk_this_call_raw ("get_" ^ cf.cf_name) (TFun(["value",false,cf.cf_type], cf.cf_type)) [	]),
 									mk_return (mk_this_call_raw ("get_" ^ cf.cf_name) (TFun(["value",false,cf.cf_type], cf.cf_type)) [	]),
-									Some { eexpr = TField (ethis, FInstance(cl, cf)); etype = cf_type; epos = pos }
+									Some { eexpr = TField (ethis, FInstance(cl, List.map snd cl.cl_params, cf)); etype = cf_type; epos = pos }
 								);
 								);
 								etype = cf_type;
 								etype = cf_type;
 								epos = pos;
 								epos = pos;
 							}
 							}
 						| Var _
 						| Var _
-						| Method MethDynamic -> { eexpr = TField (ethis, FInstance(cl,cf)); etype = cf_type; epos = pos }
+						| Method MethDynamic -> { eexpr = TField (ethis, FInstance(cl,List.map snd cl.cl_params,cf)); etype = cf_type; epos = pos }
 						| _ ->
 						| _ ->
 								{ eexpr = TField (this, FClosure(Some cl, cf)); etype = cf_type; epos = pos }
 								{ eexpr = TField (this, FClosure(Some cl, cf)); etype = cf_type; epos = pos }
 				in
 				in
@@ -7834,7 +7834,7 @@ struct
 							(if is_some if_not_inst then get if_not_inst else []) @
 							(if is_some if_not_inst then get if_not_inst else []) @
 							[{
 							[{
 								eexpr = TCall(
 								eexpr = TCall(
-									{ eexpr = TField({ eexpr = TConst TSuper; etype = TInst(cl, List.map snd cl.cl_params); epos = pos }, FInstance(cl, cf)); etype = t; epos = pos },
+									{ eexpr = TField({ eexpr = TConst TSuper; etype = TInst(cl, List.map snd cl.cl_params); epos = pos }, FInstance(cl, List.map snd cl.cl_params, cf)); etype = t; epos = pos },
 									base_arr :: (if ctx.rcf_handle_statics then [is_inst] else [])
 									base_arr :: (if ctx.rcf_handle_statics then [is_inst] else [])
 								);
 								);
 								etype = basic.tvoid;
 								etype = basic.tvoid;
@@ -8523,7 +8523,7 @@ struct
 					let expr = {
 					let expr = {
 						eexpr = TCall(
 						eexpr = TCall(
 							{
 							{
-								eexpr = (if static then TField(mk_classtype_access cl pos, FStatic(cl, cf)) else TField(this, FInstance(cl, cf)));
+								eexpr = (if static then TField(mk_classtype_access cl pos, FStatic(cl, cf)) else TField(this, FInstance(cl, List.map snd cl.cl_params, cf)));
 								etype = cf.cf_type;
 								etype = cf.cf_type;
 								epos = cf.cf_pos;
 								epos = cf.cf_pos;
 							},
 							},
@@ -10640,7 +10640,7 @@ struct
 									let vars = List.map (fun (n,_,t) -> alloc_var n t) a2 in
 									let vars = List.map (fun (n,_,t) -> alloc_var n t) a2 in
 
 
 									let args = List.map2 (fun v (_,_,t) -> mk_cast t (mk_local v f2.cf_pos)) vars a1 in
 									let args = List.map2 (fun v (_,_,t) -> mk_cast t (mk_local v f2.cf_pos)) vars a1 in
-									let field = { eexpr = TField(this, FInstance(c,f2)); etype = TFun(a1,r1); epos = p } in
+									let field = { eexpr = TField(this, FInstance(c,List.map snd c.cl_params,f2)); etype = TFun(a1,r1); epos = p } in
 									let call = { eexpr = TCall(field, args); etype = r1; epos = p } in
 									let call = { eexpr = TCall(field, args); etype = r1; epos = p } in
 									(* let call = gen.gparam_func_call call field (List.map snd f.cf_params) args in *)
 									(* let call = gen.gparam_func_call call field (List.map snd f.cf_params) args in *)
 									let is_void = is_void r2 in
 									let is_void = is_void r2 in
@@ -10705,7 +10705,7 @@ struct
 												{
 												{
 													eexpr = TField(
 													eexpr = TField(
 														{ eexpr = TConst TThis; etype = TInst(c, List.map snd c.cl_params); epos = p },
 														{ eexpr = TConst TThis; etype = TInst(c, List.map snd c.cl_params); epos = p },
-														FInstance(c,f));
+														FInstance(c,List.map snd c.cl_params,f));
 													etype = f.cf_type;
 													etype = f.cf_type;
 													epos = p
 													epos = p
 												},
 												},

+ 10 - 10
gencpp.ml

@@ -340,7 +340,7 @@ let has_meta_key meta key =
 
 
 let get_field_access_meta field_access key =
 let get_field_access_meta field_access key =
 match field_access with
 match field_access with
-   | FInstance(_,class_field)
+   | FInstance(_,_,class_field)
    | FStatic(_,class_field) -> get_meta_string class_field.cf_meta key
    | FStatic(_,class_field) -> get_meta_string class_field.cf_meta key
    | _ -> ""
    | _ -> ""
 ;;
 ;;
@@ -483,7 +483,7 @@ let is_addressOf_call func =
 let is_lvalue var =
 let is_lvalue var =
    match (remove_parens var).eexpr with
    match (remove_parens var).eexpr with
    | TLocal _ -> true
    | TLocal _ -> true
-   | TField (_,FStatic(_,field) ) | TField (_,FInstance(_,field) ) -> is_var_field field
+   | TField (_,FStatic(_,field) ) | TField (_,FInstance(_,_,field) ) -> is_var_field field
    | _ -> false
    | _ -> false
 ;;
 ;;
 
 
@@ -1823,7 +1823,7 @@ and gen_expression ctx retval expression =
                   check_array_element_cast field_object.etype "Fast" "";
                   check_array_element_cast field_object.etype "Fast" "";
 
 
                already_dynamic := (match field with
                already_dynamic := (match field with
-                  | FInstance(_,var) when is_var_field var -> true
+                  | FInstance(_,_,var) when is_var_field var -> true
                   | _ -> false);
                   | _ -> false);
             end;
             end;
          end;
          end;
@@ -1936,7 +1936,7 @@ and gen_expression ctx retval expression =
       in
       in
       let expr_type = type_string expression.etype in
       let expr_type = type_string expression.etype in
       let rec is_fixed_override e = (not (is_scalar expr_type)) && match e.eexpr with
       let rec is_fixed_override e = (not (is_scalar expr_type)) && match e.eexpr with
-      | TField(obj,FInstance(_,field) ) ->
+      | TField(obj,FInstance(_,_,field) ) ->
          let cpp_type = member_type ctx obj field.cf_name in
          let cpp_type = member_type ctx obj field.cf_name in
          (not (is_scalar cpp_type)) && (
          (not (is_scalar cpp_type)) && (
             let fixed = (cpp_type<>"?") && (expr_type<>"Dynamic") && (cpp_type<>"Dynamic") &&
             let fixed = (cpp_type<>"?") && (expr_type<>"Dynamic") && (cpp_type<>"Dynamic") &&
@@ -1950,7 +1950,7 @@ and gen_expression ctx retval expression =
       | _ -> false
       | _ -> false
       in
       in
       let check_extern_pointer_cast e = match (remove_parens e).eexpr with
       let check_extern_pointer_cast e = match (remove_parens e).eexpr with
-      | TField (_,FInstance(class_def,_) )
+      | TField (_,FInstance(class_def,_,_) )
       | TField (_,FStatic(class_def,_) )
       | TField (_,FStatic(class_def,_) )
          when class_def.cl_extern ->
          when class_def.cl_extern ->
          (try
          (try
@@ -4655,13 +4655,13 @@ class script_writer common_ctx ctx filename =
          | TField (obj,FStatic (class_def,field) ) when is_real_function field ->
          | TField (obj,FStatic (class_def,field) ) when is_real_function field ->
                   this#write ("CALLSTATIC " ^ (this#instText class_def) ^ " " ^ (this#stringText field.cf_name) ^
                   this#write ("CALLSTATIC " ^ (this#instText class_def) ^ " " ^ (this#stringText field.cf_name) ^
                      argN ^ "\n");
                      argN ^ "\n");
-         | TField (obj,FInstance (_,field) ) when (is_this obj) && (is_real_function field) ->
+         | TField (obj,FInstance (_,_,field) ) when (is_this obj) && (is_real_function field) ->
                   this#write ("CALLTHIS " ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^
                   this#write ("CALLTHIS " ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^
                      argN ^ "\n");
                      argN ^ "\n");
-         | TField (obj,FInstance (_,field) ) when is_super obj ->
+         | TField (obj,FInstance (_,_,field) ) when is_super obj ->
                   this#write ("CALLSUPER " ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^
                   this#write ("CALLSUPER " ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^
                      argN ^ "\n");
                      argN ^ "\n");
-         | TField (obj,FInstance (_,field) ) when is_real_function field ->
+         | TField (obj,FInstance (_,_,field) ) when is_real_function field ->
                   this#write ("CALLMEMBER " ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^
                   this#write ("CALLMEMBER " ^ (this#typeText obj.etype) ^ " " ^ (this#stringText field.cf_name) ^
                      argN ^ "\n");
                      argN ^ "\n");
                   this#gen_expression obj;
                   this#gen_expression obj;
@@ -4710,8 +4710,8 @@ class script_writer common_ctx ctx filename =
       | FDynamic name -> this#write ("FNAME " ^ typeText ^ " " ^ (this#stringText name) ^ "\n");
       | FDynamic name -> this#write ("FNAME " ^ typeText ^ " " ^ (this#stringText name) ^ "\n");
             this#gen_expression obj;
             this#gen_expression obj;
       | FStatic (class_def,field) -> this#write ("FSTATIC " ^ (this#instText class_def) ^ " " ^ (this#stringText field.cf_name) );
       | FStatic (class_def,field) -> this#write ("FSTATIC " ^ (this#instText class_def) ^ " " ^ (this#stringText field.cf_name) );
-      | FInstance (_,field) when is_this obj -> this#write ("FTHISINST " ^ typeText ^ " " ^ (this#stringText field.cf_name) );
-      | FInstance (_,field) -> this#write ("FLINK " ^ typeText ^ " " ^ (this#stringText field.cf_name) ^ "\n");
+      | FInstance (_,_,field) when is_this obj -> this#write ("FTHISINST " ^ typeText ^ " " ^ (this#stringText field.cf_name) );
+      | FInstance (_,_,field) -> this#write ("FLINK " ^ typeText ^ " " ^ (this#stringText field.cf_name) ^ "\n");
             this#gen_expression obj;
             this#gen_expression obj;
 
 
       | FClosure (_,field) when is_this obj -> this#write ("FTHISNAME " ^typeText ^ " " ^  (this#stringText field.cf_name) ^ "\n")
       | FClosure (_,field) when is_this obj -> this#write ("FTHISNAME " ^typeText ^ " " ^  (this#stringText field.cf_name) ^ "\n")

+ 14 - 14
gencs.ml

@@ -416,24 +416,24 @@ struct
 				(* end Std.int() *)
 				(* end Std.int() *)
 
 
 				(* TODO: change cf_name *)
 				(* TODO: change cf_name *)
-				| TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = "length" })) ->
+				| TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = "length" })) ->
 					{ e with eexpr = TField(run ef, FDynamic "Length") }
 					{ e with eexpr = TField(run ef, FDynamic "Length") }
-				| TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = "toLowerCase" })) ->
+				| TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = "toLowerCase" })) ->
 					{ e with eexpr = TField(run ef, FDynamic "ToLowerInvariant") }
 					{ e with eexpr = TField(run ef, FDynamic "ToLowerInvariant") }
-				| TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = "toUpperCase" })) ->
+				| TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = "toUpperCase" })) ->
 					{ e with eexpr = TField(run ef, FDynamic "ToUpperInvariant") }
 					{ e with eexpr = TField(run ef, FDynamic "ToUpperInvariant") }
 
 
 				| TCall( { eexpr = TField(_, FStatic({ cl_path = [], "String" }, { cf_name = "fromCharCode" })) }, [cc] ) ->
 				| TCall( { eexpr = TField(_, FStatic({ cl_path = [], "String" }, { cf_name = "fromCharCode" })) }, [cc] ) ->
 					{ e with eexpr = TNew(get_cl_from_t basic.tstring, [], [mk_cast tchar (run cc); mk_int gen 1 cc.epos]) }
 					{ e with eexpr = TNew(get_cl_from_t basic.tstring, [], [mk_cast tchar (run cc); mk_int gen 1 cc.epos]) }
-				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("charAt" as field) })) }, args )
-				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("charCodeAt" as field) })) }, args )
-				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("indexOf" as field) })) }, args )
-				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("lastIndexOf" as field) })) }, args )
-				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("split" as field) })) }, args )
-				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("substring" as field) })) }, args )
-				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("substr" as field) })) }, args ) ->
+				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("charAt" as field) })) }, args )
+				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("charCodeAt" as field) })) }, args )
+				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("indexOf" as field) })) }, args )
+				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("lastIndexOf" as field) })) }, args )
+				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("split" as field) })) }, args )
+				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("substring" as field) })) }, args )
+				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("substr" as field) })) }, args ) ->
 					{ e with eexpr = TCall(mk_static_field_access_infer string_ext field e.epos [], [run ef] @ (List.map run args)) }
 					{ e with eexpr = TCall(mk_static_field_access_infer string_ext field e.epos [], [run ef] @ (List.map run args)) }
-				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, { cf_name = ("toString") })) }, [] ) ->
+				| TCall( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, { cf_name = ("toString") })) }, [] ) ->
 					run ef
 					run ef
 				| TNew( { cl_path = ([], "String") }, [], [p] ) -> run p (* new String(myString) -> myString *)
 				| TNew( { cl_path = ([], "String") }, [], [p] ) -> run p (* new String(myString) -> myString *)
 
 
@@ -1125,7 +1125,7 @@ let configure gen =
 						expr_s w v
 						expr_s w v
 					end else
 					end else
 						do_call w e [v]
 						do_call w e [v]
-				| TField (e, (FStatic(_, cf) | FInstance(_, cf))) when Meta.has Meta.Native cf.cf_meta ->
+				| TField (e, (FStatic(_, cf) | FInstance(_, _, cf))) when Meta.has Meta.Native cf.cf_meta ->
 					let rec loop meta = match meta with
 					let rec loop meta = match meta with
 						| (Meta.Native, [EConst (String s), _],_) :: _ ->
 						| (Meta.Native, [EConst (String s), _],_) :: _ ->
 							expr_s w e; write w "."; write_field w s
 							expr_s w e; write w "."; write_field w s
@@ -1293,9 +1293,9 @@ let configure gen =
 				| TCall ({ eexpr = TLocal( { v_name = "__rethrow__" } ) }, _) ->
 				| TCall ({ eexpr = TLocal( { v_name = "__rethrow__" } ) }, _) ->
 					write w "throw"
 					write w "throw"
 				(* operator overloading handling *)
 				(* operator overloading handling *)
-				| TCall({ eexpr = TField(ef, FInstance(cl,{ cf_name = "__get" })) }, [idx]) when not (is_hxgen (TClassDecl cl)) ->
+				| TCall({ eexpr = TField(ef, FInstance(cl,_,{ cf_name = "__get" })) }, [idx]) when not (is_hxgen (TClassDecl cl)) ->
 					expr_s w { e with eexpr = TArray(ef, idx) }
 					expr_s w { e with eexpr = TArray(ef, idx) }
-				| TCall({ eexpr = TField(ef, FInstance(cl,{ cf_name = "__set" })) }, [idx; v]) when not (is_hxgen (TClassDecl cl)) ->
+				| TCall({ eexpr = TField(ef, FInstance(cl,_,{ cf_name = "__set" })) }, [idx; v]) when not (is_hxgen (TClassDecl cl)) ->
 					expr_s w { e with eexpr = TBinop(Ast.OpAssign, { e with eexpr = TArray(ef, idx) }, v) }
 					expr_s w { e with eexpr = TBinop(Ast.OpAssign, { e with eexpr = TArray(ef, idx) }, v) }
 				| TCall({ eexpr = TField(ef, FStatic(_,cf)) }, el) when PMap.mem cf.cf_name binops_names ->
 				| TCall({ eexpr = TField(ef, FStatic(_,cf)) }, el) when PMap.mem cf.cf_name binops_names ->
 					let _, elr = extract_tparams [] el in
 					let _, elr = extract_tparams [] el in

+ 3 - 3
genjava.ml

@@ -555,14 +555,14 @@ struct
 					run (mk_cast basic.tint obj)
 					run (mk_cast basic.tint obj)
 				(* end Std.int() *)
 				(* end Std.int() *)
 
 
-				| TField( ef, FInstance({ cl_path = ([], "String") }, { cf_name = "length" }) ) ->
+				| TField( ef, FInstance({ cl_path = ([], "String") }, _, { cf_name = "length" }) ) ->
 					{ e with eexpr = TCall(Type.map_expr run e, []) }
 					{ e with eexpr = TCall(Type.map_expr run e, []) }
 				| TField( ef, field ) when field_name field = "length" && is_string ef.etype ->
 				| TField( ef, field ) when field_name field = "length" && is_string ef.etype ->
 					{ e with eexpr = TCall(Type.map_expr run e, []) }
 					{ e with eexpr = TCall(Type.map_expr run e, []) }
 				| TCall( ( { eexpr = TField(ef, field) } as efield ), args ) when is_string ef.etype && String.get (field_name field) 0 = '_' ->
 				| TCall( ( { eexpr = TField(ef, field) } as efield ), args ) when is_string ef.etype && String.get (field_name field) 0 = '_' ->
 					let field = field_name field in
 					let field = field_name field in
 					{ e with eexpr = TCall({ efield with eexpr = TField(run ef, FDynamic (String.sub field 1 ( (String.length field) - 1)) )}, List.map run args) }
 					{ e with eexpr = TCall({ efield with eexpr = TField(run ef, FDynamic (String.sub field 1 ( (String.length field) - 1)) )}, List.map run args) }
-				| TCall( ( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, field )) } as efield ), args ) ->
+				| TCall( ( { eexpr = TField(ef, FInstance({ cl_path = [], "String" }, _, field )) } as efield ), args ) ->
 					let field = field.cf_name in
 					let field = field.cf_name in
 					(match field with
 					(match field with
 						| "charAt" | "charCodeAt" | "split" | "indexOf"
 						| "charAt" | "charCodeAt" | "split" | "indexOf"
@@ -707,7 +707,7 @@ let rec handle_throws gen cf =
 				) ecatches;
 				) ecatches;
 				if !needs_check_block then Type.iter iter etry;
 				if !needs_check_block then Type.iter iter etry;
 				throws := old
 				throws := old
-			| TField(e, (FInstance(_,f) | FStatic(_,f) | FClosure(_,f))) ->
+			| TField(e, (FInstance(_,_,f) | FStatic(_,f) | FClosure(_,f))) ->
 				let tdefs = collect_throws [] f.cf_meta in
 				let tdefs = collect_throws [] f.cf_meta in
 				if tdefs <> [] && not (List.for_all (fun c -> cls_any_super c !throws) tdefs) then
 				if tdefs <> [] && not (List.for_all (fun c -> cls_any_super c !throws) tdefs) then
 					raise Exit;
 					raise Exit;

+ 5 - 5
genpy.ml

@@ -410,7 +410,7 @@ module Transformer = struct
 			) length_map [] in
 			) length_map [] in
 			let c_string = match !t_string with TInst(c,_) -> c | _ -> assert false in
 			let c_string = match !t_string with TInst(c,_) -> c | _ -> assert false in
 			let cf_length = PMap.find "length" c_string.cl_fields in
 			let cf_length = PMap.find "length" c_string.cl_fields in
-			let ef = mk (TField(e1,FInstance(c_string,cf_length))) !t_int e1.epos in
+			let ef = mk (TField(e1,FInstance(c_string,[],cf_length))) !t_int e1.epos in
 			let res_var = alloc_var (ae.a_next_id()) ef.etype in
 			let res_var = alloc_var (ae.a_next_id()) ef.etype in
 			let res_local = {ef with eexpr = TLocal res_var} in
 			let res_local = {ef with eexpr = TLocal res_var} in
 			let var_expr = {ef with eexpr = TVar(res_var,Some ef)} in
 			let var_expr = {ef with eexpr = TVar(res_var,Some ef)} in
@@ -1333,7 +1333,7 @@ module Printer = struct
 		in
 		in
 		let name = field_name fa in
 		let name = field_name fa in
 		let is_extern = (match fa with
 		let is_extern = (match fa with
-		| FInstance(c,_) -> c.cl_extern
+		| FInstance(c,_,_) -> c.cl_extern
 		| FStatic(c,_) -> c.cl_extern
 		| FStatic(c,_) -> c.cl_extern
 		| _ -> false)
 		| _ -> false)
 		in
 		in
@@ -1347,9 +1347,9 @@ module Printer = struct
 		in
 		in
 		match fa with
 		match fa with
 			(* we need to get rid of these cases in the transformer, how is this handled in js *)
 			(* we need to get rid of these cases in the transformer, how is this handled in js *)
-			| FInstance(c,{cf_name = "length" | "get_length"}) when (is_type "" "list")(TClassDecl c) ->
+			| FInstance(c,_,{cf_name = "length" | "get_length"}) when (is_type "" "list")(TClassDecl c) ->
 				Printf.sprintf "python_lib_Builtin.len(%s)" (print_expr pctx e1)
 				Printf.sprintf "python_lib_Builtin.len(%s)" (print_expr pctx e1)
-			| FInstance(c,{cf_name = "length"}) when (is_type "" "String")(TClassDecl c) ->
+			| FInstance(c,_,{cf_name = "length"}) when (is_type "" "String")(TClassDecl c) ->
 				Printf.sprintf "python_lib_Builtin.len(%s)" (print_expr pctx e1)
 				Printf.sprintf "python_lib_Builtin.len(%s)" (print_expr pctx e1)
 			| FStatic(c,{cf_name = "fromCharCode"}) when (is_type "" "String")(TClassDecl c) ->
 			| FStatic(c,{cf_name = "fromCharCode"}) when (is_type "" "String")(TClassDecl c) ->
 				Printf.sprintf "HxString.fromCharCode"
 				Printf.sprintf "HxString.fromCharCode"
@@ -1777,7 +1777,7 @@ module Generator = struct
 			| _,Some ({eexpr = TFunction f} as ef) ->
 			| _,Some ({eexpr = TFunction f} as ef) ->
 				let ethis = mk (TConst TThis) (TInst(c,List.map snd c.cl_params)) cf.cf_pos in
 				let ethis = mk (TConst TThis) (TInst(c,List.map snd c.cl_params)) cf.cf_pos in
 				let member_data = List.map (fun cf ->
 				let member_data = List.map (fun cf ->
-					let ef = mk (TField(ethis,FInstance(c, cf))) cf.cf_type cf.cf_pos in
+					let ef = mk (TField(ethis,FInstance(c,[],cf))) cf.cf_type cf.cf_pos in (* TODO *)
 					mk (TBinop(OpAssign,ef,null ef.etype ef.epos)) ef.etype ef.epos
 					mk (TBinop(OpAssign,ef,null ef.etype ef.epos)) ef.etype ef.epos
 				) member_inits in
 				) member_inits in
 				let e = {f.tf_expr with eexpr = TBlock (member_data @ [f.tf_expr])} in
 				let e = {f.tf_expr with eexpr = TBlock (member_data @ [f.tf_expr])} in

+ 1 - 1
genswf9.ml

@@ -2059,7 +2059,7 @@ let check_constructor ctx c f =
 		Type.iter loop e;
 		Type.iter loop e;
 		match e.eexpr with
 		match e.eexpr with
 		| TCall ({ eexpr = TConst TSuper },_) -> raise Exit
 		| TCall ({ eexpr = TConst TSuper },_) -> raise Exit
-		| TBinop (OpAssign,{ eexpr = TField({ eexpr = TConst TThis },FInstance (cc,cf)) },_) when c != cc && (match classify ctx cf.cf_type with KFloat | KDynamic -> true | _ -> false) ->
+		| TBinop (OpAssign,{ eexpr = TField({ eexpr = TConst TThis },FInstance (cc,_,cf)) },_) when c != cc && (match classify ctx cf.cf_type with KFloat | KDynamic -> true | _ -> false) ->
 			error "You cannot assign some super class vars before calling super() in flash, this will reset them to default value" e.epos
 			error "You cannot assign some super class vars before calling super() in flash, this will reset them to default value" e.epos
 		| _ -> ()
 		| _ -> ()
 	in
 	in

+ 4 - 2
interp.ml

@@ -4526,7 +4526,7 @@ and encode_tfunc func =
 
 
 and encode_field_access fa =
 and encode_field_access fa =
 	let tag,pl = match fa with
 	let tag,pl = match fa with
-		| FInstance(c,cf) -> 0,[encode_clref c;encode_cfref cf]
+		| FInstance(c,_,cf) -> 0,[encode_clref c;encode_cfref cf] (* TODO: breaking change, kind of *)
 		| FStatic(c,cf) -> 1,[encode_clref c;encode_cfref cf]
 		| FStatic(c,cf) -> 1,[encode_clref c;encode_cfref cf]
 		| FAnon(cf) -> 2,[encode_cfref cf]
 		| FAnon(cf) -> 2,[encode_cfref cf]
 		| FDynamic(s) -> 3,[enc_string s]
 		| FDynamic(s) -> 3,[enc_string s]
@@ -4676,7 +4676,9 @@ let decode_efield v =
 
 
 let decode_field_access v =
 let decode_field_access v =
 	match decode_enum v with
 	match decode_enum v with
-	| 0, [c;cf] -> FInstance(decode_ref c,decode_ref cf)
+	| 0, [c;cf] ->
+		let c = decode_ref c in
+		FInstance(c,List.map snd c.cl_params,decode_ref cf) (* TODO: breaking change? *)
 	| 1, [c;cf] -> FStatic(decode_ref c,decode_ref cf)
 	| 1, [c;cf] -> FStatic(decode_ref c,decode_ref cf)
 	| 2, [cf] -> FAnon(decode_ref cf)
 	| 2, [cf] -> FAnon(decode_ref cf)
 	| 3, [s] -> FDynamic(dec_string s)
 	| 3, [s] -> FDynamic(dec_string s)

+ 5 - 5
optimizer.ml

@@ -1099,7 +1099,7 @@ let rec reduce_loop ctx e =
 		| None -> reduce_expr ctx e
 		| None -> reduce_expr ctx e
 		| Some e -> reduce_loop ctx e)
 		| Some e -> reduce_loop ctx e)
 	| TCall ({ eexpr = TField (o,FClosure (c,cf)) } as f,el) ->
 	| TCall ({ eexpr = TField (o,FClosure (c,cf)) } as f,el) ->
-		let fmode = (match c with None -> FAnon cf | Some c -> FInstance (c,cf)) in
+		let fmode = (match c with None -> FAnon cf | Some c -> FInstance (c,[],cf)) in (* TODO *)
 		{ e with eexpr = TCall ({ f with eexpr = TField (o,fmode) },el) }
 		{ e with eexpr = TCall ({ f with eexpr = TField (o,fmode) },el) }
 	| TSwitch (e1,[[{eexpr = TConst (TBool true)}],{eexpr = TConst (TBool true)}],Some ({eexpr = TConst (TBool false)})) ->
 	| TSwitch (e1,[[{eexpr = TConst (TBool true)}],{eexpr = TConst (TBool true)}],Some ({eexpr = TConst (TBool false)})) ->
 		(* introduced by extractors in some cases *)
 		(* introduced by extractors in some cases *)
@@ -1244,7 +1244,7 @@ let inline_constructors ctx e =
 								match e.eexpr with
 								match e.eexpr with
 								| TBlock el ->
 								| TBlock el ->
 									List.iter get_assigns el
 									List.iter get_assigns el
-								| TBinop (OpAssign, { eexpr = TField ({ eexpr = TLocal vv },FInstance(_,cf)); etype = t }, e) when v == vv ->
+								| TBinop (OpAssign, { eexpr = TField ({ eexpr = TLocal vv },FInstance(_,_,cf)); etype = t }, e) when v == vv ->
 									assigns := (cf.cf_name,e,t) :: !assigns
 									assigns := (cf.cf_name,e,t) :: !assigns
 								| _ ->
 								| _ ->
 									raise Exit
 									raise Exit
@@ -1269,7 +1269,7 @@ let inline_constructors ctx e =
 					end
 					end
 				| None -> ()
 				| None -> ()
 			end
 			end
-		| TField({eexpr = TLocal v}, (FInstance(_, {cf_kind = Var _; cf_name = s}) | FAnon({cf_kind = Var _; cf_name = s}))) ->
+		| TField({eexpr = TLocal v}, (FInstance(_, _, {cf_kind = Var _; cf_name = s}) | FAnon({cf_kind = Var _; cf_name = s}))) ->
 			()
 			()
 		| TArray ({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 ->
 		| TArray ({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 ->
 			let (_,_,fields,_,_) = PMap.find (-v.v_id) !vars in
 			let (_,_,fields,_,_) = PMap.find (-v.v_id) !vars in
@@ -1279,7 +1279,7 @@ let inline_constructors ctx e =
 			begin match e1.eexpr with
 			begin match e1.eexpr with
 				| TArray ({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 && not (is_valid_field v (Int32.to_string i)) ->
 				| TArray ({eexpr = TLocal v},{eexpr = TConst (TInt i)}) when v.v_id < 0 && not (is_valid_field v (Int32.to_string i)) ->
 					cancel v
 					cancel v
-				| TField({eexpr = TLocal v}, (FInstance(_, {cf_kind = Var _; cf_name = s}) | FAnon({cf_kind = Var _; cf_name = s}))) when v.v_id < 0 && not (is_valid_field v s) ->
+				| TField({eexpr = TLocal v}, (FInstance(_, _, {cf_kind = Var _; cf_name = s}) | FAnon({cf_kind = Var _; cf_name = s}))) when v.v_id < 0 && not (is_valid_field v s) ->
 					cancel v
 					cancel v
 				| _ ->
 				| _ ->
 					find_locals e1
 					find_locals e1
@@ -1323,7 +1323,7 @@ let inline_constructors ctx e =
 				in
 				in
 				List.iter (fun (v,e) -> append (mk (TVar(v,Some (subst e))) ctx.t.tvoid e.epos)) (List.rev vars);
 				List.iter (fun (v,e) -> append (mk (TVar(v,Some (subst e))) ctx.t.tvoid e.epos)) (List.rev vars);
 				mk (TVar (v_first, Some (subst e_first))) ctx.t.tvoid e.epos
 				mk (TVar (v_first, Some (subst e_first))) ctx.t.tvoid e.epos
-			| TField ({ eexpr = TLocal v },FInstance (c,cf)) when v.v_id < 0 ->
+			| TField ({ eexpr = TLocal v },FInstance (c,_,cf)) when v.v_id < 0 ->
 				let (_, vars),el_init = PMap.find (-v.v_id) vfields in
 				let (_, vars),el_init = PMap.find (-v.v_id) vfields in
 				(try
 				(try
 					let v = PMap.find cf.cf_name vars in
 					let v = PMap.find cf.cf_name vars in

+ 18 - 17
type.ml

@@ -132,7 +132,7 @@ and texpr_expr =
 	| TEnumParameter of texpr * tenum_field * int
 	| TEnumParameter of texpr * tenum_field * int
 
 
 and tfield_access =
 and tfield_access =
-	| FInstance of tclass * tclass_field
+	| FInstance of tclass * tparams * tclass_field
 	| FStatic of tclass * tclass_field
 	| FStatic of tclass * tclass_field
 	| FAnon of tclass_field
 	| FAnon of tclass_field
 	| FDynamic of string
 	| FDynamic of string
@@ -616,12 +616,12 @@ let is_closed a = !(a.a_status) <> Opened
 
 
 let field_name f =
 let field_name f =
 	match f with
 	match f with
-	| FAnon f | FInstance (_,f) | FStatic (_,f) | FClosure (_,f) -> f.cf_name
+	| FAnon f | FInstance (_,_,f) | FStatic (_,f) | FClosure (_,f) -> f.cf_name
 	| FEnum (_,f) -> f.ef_name
 	| FEnum (_,f) -> f.ef_name
 	| FDynamic n -> n
 	| FDynamic n -> n
 
 
 let extract_field = function
 let extract_field = function
-	| FAnon f | FInstance (_,f) | FStatic (_,f) | FClosure (_,f) -> Some f
+	| FAnon f | FInstance (_,_,f) | FStatic (_,f) | FClosure (_,f) -> Some f
 	| _ -> None
 	| _ -> None
 
 
 let is_extern_field f =
 let is_extern_field f =
@@ -635,19 +635,20 @@ let field_type f =
 	| [] -> f.cf_type
 	| [] -> f.cf_type
 	| l -> monomorphs l f.cf_type
 	| l -> monomorphs l f.cf_type
 
 
-let rec raw_class_field build_type c i =
+let rec raw_class_field build_type c tl i =
+	let apply = apply_params c.cl_params tl in
 	try
 	try
 		let f = PMap.find i c.cl_fields in
 		let f = PMap.find i c.cl_fields in
-		Some c, build_type f , f
+		Some (c,tl), build_type f , f
 	with Not_found -> try (match c.cl_constructor with
 	with Not_found -> try (match c.cl_constructor with
-		| Some ctor when i = "new" -> Some c, build_type ctor,ctor
+		| Some ctor when i = "new" -> Some (c,tl), build_type ctor,ctor
 		| _ -> raise Not_found)
 		| _ -> raise Not_found)
 	with Not_found -> try
 	with Not_found -> try
 		match c.cl_super with
 		match c.cl_super with
 		| None ->
 		| None ->
 			raise Not_found
 			raise Not_found
 		| Some (c,tl) ->
 		| Some (c,tl) ->
-			let c2 , t , f = raw_class_field build_type c i in
+			let c2 , t , f = raw_class_field build_type c (List.map apply tl) i in
 			c2, apply_params c.cl_params tl t , f
 			c2, apply_params c.cl_params tl t , f
 	with Not_found ->
 	with Not_found ->
 		match c.cl_kind with
 		match c.cl_kind with
@@ -663,10 +664,10 @@ let rec raw_class_field build_type c i =
 							None, build_type f, f
 							None, build_type f, f
 						with
 						with
 							Not_found -> loop ctl)
 							Not_found -> loop ctl)
-					| TInst (c,pl) ->
+					| TInst (c,tl) ->
 						(try
 						(try
-							let c2, t , f = raw_class_field build_type c i in
-							c2, apply_params c.cl_params pl t, f
+							let c2, t , f = raw_class_field build_type c (List.map apply tl) i in
+							c2, apply_params c.cl_params tl t, f
 						with
 						with
 							Not_found -> loop ctl)
 							Not_found -> loop ctl)
 					| _ ->
 					| _ ->
@@ -684,7 +685,7 @@ let rec raw_class_field build_type c i =
 					raise Not_found
 					raise Not_found
 				| (c,tl) :: l ->
 				| (c,tl) :: l ->
 					try
 					try
-						let c2, t , f = raw_class_field build_type c i in
+						let c2, t , f = raw_class_field build_type c (List.map apply tl) i in
 						c2, apply_params c.cl_params tl t, f
 						c2, apply_params c.cl_params tl t, f
 					with
 					with
 						Not_found -> loop l
 						Not_found -> loop l
@@ -695,9 +696,9 @@ let class_field = raw_class_field field_type
 
 
 let quick_field t n =
 let quick_field t n =
 	match follow t with
 	match follow t with
-	| TInst (c,_) ->
-		let c, _, f = raw_class_field (fun f -> f.cf_type) c n in
-		(match c with None -> FAnon f | Some c -> FInstance (c,f))
+	| TInst (c,tl) ->
+		let c, _, f = raw_class_field (fun f -> f.cf_type) c tl n in
+		(match c with None -> FAnon f | Some (c,tl) -> FInstance (c,tl,f))
 	| TAnon a ->
 	| TAnon a ->
 		(match !(a.a_status) with
 		(match !(a.a_status) with
 		| EnumStatics e ->
 		| EnumStatics e ->
@@ -865,7 +866,7 @@ let rec s_expr s_type e =
 	| TField (e,f) ->
 	| TField (e,f) ->
 		let fstr = (match f with
 		let fstr = (match f with
 			| FStatic (c,f) -> "static(" ^ s_type_path c.cl_path ^ "." ^ f.cf_name ^ ")"
 			| FStatic (c,f) -> "static(" ^ s_type_path c.cl_path ^ "." ^ f.cf_name ^ ")"
-			| FInstance (c,f) -> "inst(" ^ s_type_path c.cl_path ^ "." ^ f.cf_name ^ " : " ^ s_type f.cf_type ^ ")"
+			| FInstance (c,_,f) -> "inst(" ^ s_type_path c.cl_path ^ "." ^ f.cf_name ^ " : " ^ s_type f.cf_type ^ ")"
 			| FClosure (c,f) -> "closure(" ^ (match c with None -> f.cf_name | Some c -> s_type_path c.cl_path ^ "." ^ f.cf_name)  ^ ")"
 			| FClosure (c,f) -> "closure(" ^ (match c with None -> f.cf_name | Some c -> s_type_path c.cl_path ^ "." ^ f.cf_name)  ^ ")"
 			| FAnon f -> "anon(" ^ f.cf_name ^ ")"
 			| FAnon f -> "anon(" ^ f.cf_name ^ ")"
 			| FEnum (en,f) -> "enum(" ^ s_type_path en.e_path ^ "." ^ f.ef_name ^ ")"
 			| FEnum (en,f) -> "enum(" ^ s_type_path en.e_path ^ "." ^ f.ef_name ^ ")"
@@ -1340,7 +1341,7 @@ let rec unify a b =
 			| _ -> ());
 			| _ -> ());
 		(try
 		(try
 			PMap.iter (fun n f2 ->
 			PMap.iter (fun n f2 ->
-				let _, ft, f1 = (try class_field c n with Not_found -> error [has_no_field a n]) in
+				let _, ft, f1 = (try class_field c tl n with Not_found -> error [has_no_field a n]) in
 				if not (unify_kind f1.cf_kind f2.cf_kind) then error [invalid_kind n f1.cf_kind f2.cf_kind];
 				if not (unify_kind f1.cf_kind f2.cf_kind) then error [invalid_kind n f1.cf_kind f2.cf_kind];
 				if f2.cf_public && not f1.cf_public then error [invalid_visibility n];
 				if f2.cf_public && not f1.cf_public then error [invalid_visibility n];
 				(try
 				(try
@@ -1827,7 +1828,7 @@ let map_expr_type f ft fv e =
 		let v = try
 		let v = try
 			let n = match v with
 			let n = match v with
 				| FClosure _ -> raise Not_found
 				| FClosure _ -> raise Not_found
-				| FAnon f | FInstance (_,f) | FStatic (_,f) -> f.cf_name
+				| FAnon f | FInstance (_,_,f) | FStatic (_,f) -> f.cf_name
 				| FEnum (_,f) -> f.ef_name
 				| FEnum (_,f) -> f.ef_name
 				| FDynamic n -> n
 				| FDynamic n -> n
 			in
 			in

+ 15 - 1
typecore.ml

@@ -122,13 +122,20 @@ and typer = {
 	mutable on_error : typer -> string -> pos -> unit;
 	mutable on_error : typer -> string -> pos -> unit;
 }
 }
 
 
-type error_msg =
+type call_error =
+	| Not_enough_arguments
+	| Too_many_arguments
+	| Could_not_unify of error_msg
+	| Cannot_skip_non_nullable of string
+
+and error_msg =
 	| Module_not_found of path
 	| Module_not_found of path
 	| Type_not_found of path * string
 	| Type_not_found of path * string
 	| Unify of unify_error list
 	| Unify of unify_error list
 	| Custom of string
 	| Custom of string
 	| Unknown_ident of string
 	| Unknown_ident of string
 	| Stack of error_msg * error_msg
 	| Stack of error_msg * error_msg
+	| Call_error of call_error
 
 
 exception Fatal_error of string * Ast.pos
 exception Fatal_error of string * Ast.pos
 
 
@@ -253,6 +260,13 @@ let rec error_msg = function
 	| Unknown_ident s -> "Unknown identifier : " ^ s
 	| Unknown_ident s -> "Unknown identifier : " ^ s
 	| Custom s -> s
 	| Custom s -> s
 	| Stack (m1,m2) -> error_msg m1 ^ "\n" ^ error_msg m2
 	| Stack (m1,m2) -> error_msg m1 ^ "\n" ^ error_msg m2
+	| Call_error err -> s_call_error err
+
+and s_call_error = function
+	| Not_enough_arguments -> "Not enough arguments"
+	| Too_many_arguments -> "Too many arguments"
+	| Could_not_unify err -> error_msg err
+	| Cannot_skip_non_nullable s -> "Cannot skip non-nullable argument " ^ s
 
 
 let pass_name = function
 let pass_name = function
 	| PBuildModule -> "build-module"
 	| PBuildModule -> "build-module"

+ 5 - 5
typeload.ml

@@ -452,7 +452,7 @@ and load_complex_type ctx p t =
 					c2.cl_private <- true;
 					c2.cl_private <- true;
 					PMap.iter (fun f _ ->
 					PMap.iter (fun f _ ->
 						try
 						try
-							ignore(class_field c f);
+							ignore(class_field c tl f);
 							error ("Cannot redefine field " ^ f) p
 							error ("Cannot redefine field " ^ f) p
 						with
 						with
 							Not_found -> ()
 							Not_found -> ()
@@ -859,9 +859,9 @@ let check_overriding ctx c =
 						) overloads
 						) overloads
 					) true
 					) true
 				) f.cf_overloads
 				) f.cf_overloads
-	  end else
+			end else
 				check_field f (fun csup i ->
 				check_field f (fun csup i ->
-					let _, t, f2 = raw_class_field (fun f -> f.cf_type) csup i in
+					let _, t, f2 = raw_class_field (fun f -> f.cf_type) csup params i in
 					t, f2) false
 					t, f2) false
 		) c.cl_fields
 		) c.cl_fields
 
 
@@ -875,7 +875,7 @@ let class_field_no_interf c i =
 			raise Not_found
 			raise Not_found
 		| Some (c,tl) ->
 		| Some (c,tl) ->
 			(* rec over class_field *)
 			(* rec over class_field *)
-			let _, t , f = raw_class_field (fun f -> f.cf_type) c i in
+			let _, t , f = raw_class_field (fun f -> f.cf_type) c tl i in
 			apply_params c.cl_params tl t , f
 			apply_params c.cl_params tl t , f
 
 
 let rec check_interface ctx c intf params =
 let rec check_interface ctx c intf params =
@@ -2107,7 +2107,7 @@ let init_class ctx c p context_init herits fields =
 			let check_method m t req_name =
 			let check_method m t req_name =
 				if ctx.com.display <> DMNone then () else
 				if ctx.com.display <> DMNone then () else
 				try
 				try
-					let _, t2, f = (if stat then let f = PMap.find m c.cl_statics in Some c, f.cf_type, f else class_field c m) in
+					let _, t2, f = (if stat then let f = PMap.find m c.cl_statics in None, f.cf_type, f else class_field c (List.map snd c.cl_params) m) in
 					(* accessors must be public on As3 (issue #1872) *)
 					(* accessors must be public on As3 (issue #1872) *)
 					if Common.defined ctx.com Define.As3 then f.cf_meta <- (Meta.Public,[],p) :: f.cf_meta;
 					if Common.defined ctx.com Define.As3 then f.cf_meta <- (Meta.Public,[],p) :: f.cf_meta;
 					(match f.cf_kind with
 					(match f.cf_kind with

+ 189 - 215
typer.ml

@@ -239,8 +239,8 @@ let field_type ctx c pl f p =
 		if not (Meta.has Meta.Generic f.cf_meta) then add_constraint_checks ctx c.cl_params pl f monos p;
 		if not (Meta.has Meta.Generic f.cf_meta) then add_constraint_checks ctx c.cl_params pl f monos p;
 		apply_params l monos f.cf_type
 		apply_params l monos f.cf_type
 
 
-let class_field ctx c pl name p =
-	raw_class_field (fun f -> field_type ctx c pl f p) c name
+let class_field ctx c tl name p =
+	raw_class_field (fun f -> field_type ctx c tl f p) c tl name
 
 
 (* checks if we can access to a given class field using current context *)
 (* checks if we can access to a given class field using current context *)
 let rec can_access ctx ?(in_overload=false) c cf stat =
 let rec can_access ctx ?(in_overload=false) c cf stat =
@@ -667,155 +667,133 @@ let is_forced_inline c cf =
 	| _ when Meta.has Meta.Extern cf.cf_meta -> true
 	| _ when Meta.has Meta.Extern cf.cf_meta -> true
 	| _ -> false
 	| _ -> false
 
 
-let rec unify_call_args ctx ?(overloads=None) cf el args r p inline =
-	(* 'overloads' will carry a ( return_result ) list, called 'compatible' *)
-	(* it's used to correctly support an overload selection algorithm *)
-	let overloads, compatible, legacy = match cf, overloads with
-		| Some(TInst(c,pl),f), None when ctx.com.config.pf_overload && Meta.has Meta.Overload f.cf_meta ->
-				let overloads = List.filter (fun (_,f2) ->
-					not (f == f2) && (f2.cf_public || can_access ctx ~in_overload:true c f2 false)
-				) (Typeload.get_overloads c f.cf_name) in
-				if overloads = [] then (* is static function *)
-					let overloads = List.map (fun f -> f.cf_type, f) f.cf_overloads in
-					let is_static = f.cf_name <> "new" in
-					List.filter (fun (_,f) -> can_access ctx ~in_overload:true c f is_static) overloads, [], false
-				else
-					overloads, [], false
-		| Some(_,f), None ->
-				List.map (fun f -> f.cf_type, f) f.cf_overloads, [], true
-		| _, Some s ->
-				s
-		| _ -> [], [], true
-	in
-	let next ?retval () =
-		let compatible = Option.map_default (fun r -> r :: compatible) compatible retval in
-		match cf, overloads with
-		| Some (TInst(c,pl),_), (ft,o) :: l ->
-			let o = { o with cf_type = ft } in
-			let args, ret = (match follow (apply_params c.cl_params pl (field_type ctx c pl o p)) with (* I'm getting non-followed types here. Should it happen? *)
-				| TFun (tl,t) -> tl, t
-				| _ -> assert false
-			) in
-			Some (unify_call_args ctx ~overloads:(Some (l,compatible,legacy)) (Some (TInst(c,pl),o)) el args ret p inline)
-		| Some (t,_), (ft,o) :: l ->
-			let o = { o with cf_type = ft } in
-			let args, ret = (match Type.field_type o with
-				| TFun (tl,t) -> tl, t
-				| _ -> assert false
-			) in
-			Some (unify_call_args ctx ~overloads:(Some (l,compatible,legacy)) (Some (t, o)) el args ret p inline)
-		| _ ->
-			match compatible with
-			| [] -> None
-			| [acc,t] -> Some (List.map fst acc, t)
-			| comp ->
-				match Codegen.Overloads.reduce_compatible compatible with
-				| [acc,t] -> Some (List.map fst acc, t)
-				| (acc,t) :: _ -> (* ambiguous overload *)
-					let name = match cf with | Some(_,f) -> "'" ^ f.cf_name ^ "' " | _ -> "" in
-					let format_amb = String.concat "\n" (List.map (fun (_,t) ->
-						"Function " ^ name ^ "with type " ^ (s_type (print_context()) t)
-					) compatible) in
-					display_error ctx ("This call is ambiguous between the following methods:\n" ^ format_amb) p;
-					Some (List.map fst acc,t)
-				| [] -> None
-	in
-	let fun_details() =
-		let format_arg = (fun (name,opt,_) -> (if opt then "?" else "") ^ name) in
-		"Function " ^ (match cf with None -> "" | Some (_,f) -> "'" ^ f.cf_name ^ "' ") ^ "requires " ^ (if args = [] then "no arguments" else "arguments : " ^ String.concat ", " (List.map format_arg args))
-	in
-	let invalid_skips = ref [] in
-	let error acc txt =
-		match next() with
-		| Some l -> l
-		| None ->
-		display_error ctx (txt ^ " arguments\n" ^ (fun_details())) p;
-		List.rev (List.map fst acc), (TFun(args,r))
+let rec unify_call_args' ctx el args r p inline force_inline =
+	let call_error err p =
+		raise (Error (Call_error err,p))
 	in
 	in
 	let arg_error ul name opt p =
 	let arg_error ul name opt p =
-		match next() with
-		| Some l -> l
-		| None -> raise (Error (Stack (Unify ul,Custom ("For " ^ (if opt then "optional " else "") ^ "function argument '" ^ name ^ "'")), p))
+		let err = Stack (Unify ul,Custom ("For " ^ (if opt then "optional " else "") ^ "function argument '" ^ name ^ "'")) in
+		call_error (Could_not_unify err) p
 	in
 	in
-	let rec no_opt = function
-		| [] -> []
-		| ({ eexpr = TConst TNull },true) :: l -> no_opt l
-		| l -> l
-	in
-	let rec default_value t po =
+	let rec default_value name t =
 		if is_pos_infos t then
 		if is_pos_infos t then
 			let infos = mk_infos ctx p [] in
 			let infos = mk_infos ctx p [] in
 			let e = type_expr ctx infos (WithType t) in
 			let e = type_expr ctx infos (WithType t) in
-			(e, true)
-		else begin
-			if not ctx.com.config.pf_can_skip_non_nullable_argument then begin match po with
-				| Some (name,p) when not (is_nullable t) -> invalid_skips := (name,p) :: !invalid_skips;
-				| _ -> ()
-			end;
-			(null (ctx.t.tnull t) p, true)
-		end
+			e
+		else
+			null (ctx.t.tnull t) p
 	in
 	in
-	let force_inline, is_extern = match cf with Some(TInst(c,_),f) -> is_forced_inline (Some c) f, c.cl_extern | _ -> false, false in
-	let rec loop acc l l2 skip check_rest =
-		match l , l2 with
-		| [] , [] ->
-			begin match !invalid_skips with
-				| [] -> ()
-				| skips -> List.iter (fun (name,p) -> display_error ctx ("Cannot skip non-nullable argument " ^ name) p) skips
-			end;
-			let args,tf = if not (inline && (ctx.g.doinline || force_inline)) && not ctx.com.config.pf_pad_nulls then
-				List.rev (no_opt acc), (TFun(args,r))
-			else
-				List.rev (acc), (TFun(args,r))
-			in
-			if not legacy && ctx.com.config.pf_overload then
-				match next ~retval:(args,tf) () with
-				| Some l -> l
-				| None ->
-					display_error ctx ("No overloaded function matches the arguments. Are the arguments correctly typed?") p;
-					List.map fst args, tf
-			else
-				List.map fst args, tf
-		| l , [(name,opt,t)] when check_rest ->
-			(match follow t with
+	let skipped = ref [] in
+	let skip name ul t =
+		if not ctx.com.config.pf_can_skip_non_nullable_argument && not (is_nullable t) then
+			call_error (Cannot_skip_non_nullable name) p;
+		skipped := (name,ul) :: !skipped;
+		default_value name t
+	in
+	(* let force_inline, is_extern = match cf with Some(TInst(c,_),f) -> is_forced_inline (Some c) f, c.cl_extern | _ -> false, false in *)
+	let force_inline, is_extern = false, false in
+	let type_against t e =
+		let e = type_expr ctx e (WithTypeResume t) in
+		(try unify_raise ctx e.etype t e.epos with Error (Unify l,p) -> raise (WithTypeError (l,p)));
+		let e = Codegen.AbstractCast.check_cast ctx t e p in
+		e
+	in
+	let rec loop el args = match el,args with
+		| [],[] ->
+			[]
+		| _,[name,false,t] when (match follow t with TAbstract({a_path = ["haxe"],"Rest"},_) -> true | _ -> false) ->
+			begin match follow t with
 				| TAbstract({a_path=(["haxe"],"Rest")},[t]) ->
 				| TAbstract({a_path=(["haxe"],"Rest")},[t]) ->
-					let rec process acc el =
-						match el with
-						| [] -> acc
-						| ee :: rest ->
-							let e = type_expr ctx ee (WithTypeResume t) in
-							begin try
-								unify_raise ctx e.etype t e.epos
-							with Error (Unify ul,p) ->
-								raise (Error (Stack (Unify ul,Custom ("For rest function argument '" ^ name ^ "'")), p))
-							end;
-							process ((Codegen.AbstractCast.check_cast ctx t e p,false) :: acc) rest
-					in
-					loop (process acc l) [] [] skip false
+					(try List.map (fun e -> type_against t e,false) el with WithTypeError(ul,p) -> arg_error ul name false p)
 				| _ ->
 				| _ ->
-					loop acc l l2 skip false)
-		| [] , (_,false,_) :: _ ->
-			error (List.fold_left (fun acc (_,_,t) -> default_value t None :: acc) acc l2) "Not enough"
-		| [] , (name,true,t) :: l ->
-			loop (default_value t None :: acc) [] l skip check_rest
-		| _ , [] ->
-			(match List.rev skip with
-			| [] -> error acc "Too many"
-			| [name,ul] -> arg_error ul name true p
-			| (name,ul) :: _ -> arg_error (Unify_custom ("Invalid arguments\n" ^ fun_details()) :: ul) name true p)
-		| ee :: l, (name,opt,t) :: l2 ->
-			try
-				let e = type_expr ctx ee (WithTypeResume t) in
-				(try unify_raise ctx e.etype t e.epos with Error (Unify l,p) -> raise (WithTypeError (l,p)));
-				loop ((Codegen.AbstractCast.check_cast ctx t e p,false) :: acc) l l2 skip check_rest
+					assert false
+			end
+		| [],(_,false,_) :: _ ->
+			call_error Not_enough_arguments p
+		| [],(name,true,t) :: args ->
+			begin match loop [] args with
+				| [] when not (inline && (ctx.g.doinline || force_inline)) && not ctx.com.config.pf_pad_nulls -> []
+				| args ->
+					let e_def = default_value name t in
+					(e_def,true) :: args
+			end
+		| (_,p) :: _, [] ->
+			begin match List.rev !skipped with
+				| [] -> call_error Too_many_arguments p
+				| (s,ul) :: _ -> arg_error ul s true p
+			end
+		| e :: el,(name,opt,t) :: args ->
+			begin try
+				let e = type_against t e in
+				(e,opt) :: loop el args
 			with
 			with
 				WithTypeError (ul,p) ->
 				WithTypeError (ul,p) ->
 					if opt then
 					if opt then
-						loop (default_value t (Some (name,p)) :: acc) (ee :: l) l2 ((name,ul) :: skip) check_rest
+						let e_def = skip name ul t in
+						(e_def,true) :: loop (e :: el) args
 					else
 					else
 						arg_error ul name false p
 						arg_error ul name false p
+			end
+	in
+	let el = loop el args in
+	el,TFun(args,r)
+
+let unify_call_args ctx el args r p inline force_inline =
+	let el,tf = unify_call_args' ctx el args r p inline force_inline in
+	List.map fst el,tf
+
+let unify_field_call ctx fa el args ret p inline =
+	let map_cf map cf = map (monomorphs cf.cf_params cf.cf_type),cf in
+	let expand_overloads map cf =
+		(TFun(args,ret),cf) :: (List.map (map_cf map) cf.cf_overloads)
+	in
+	let candidates,co,cf,mk_fa = match fa with
+		| FStatic(c,cf) ->
+			expand_overloads (fun t -> t) cf,Some c,cf,(fun cf -> FStatic(c,cf))
+		| FAnon cf ->
+			expand_overloads (fun t -> t) cf,None,cf,(fun cf -> FAnon cf)
+		| FInstance(c,tl,cf) ->
+			let map = apply_params c.cl_params tl in
+			let cfl = if cf.cf_name = "new" || not (Meta.has Meta.Overload cf.cf_meta && ctx.com.config.pf_overload) then
+				List.map (map_cf map) cf.cf_overloads
+			else
+				List.map (fun (t,cf) -> map (monomorphs cf.cf_params t),cf) (Typeload.get_overloads c cf.cf_name)
+			in
+			(TFun(args,ret),cf) :: cfl,None,cf,(fun cf -> FInstance(c,tl,cf))
+		| _ ->
+			error "Invalid field call" p
+	in
+	let is_forced_inline = is_forced_inline co cf in
+	let is_overload = Meta.has Meta.Overload cf.cf_meta in
+	let candidates,failures = List.fold_left (fun (candidates,failures) (t,cf) ->
+		begin try
+			begin match follow t with
+				| TFun(args,ret) ->
+				let el,tf = unify_call_args' ctx el args ret p inline is_forced_inline in
+					let mk_call ethis =
+						let ef = mk (TField(ethis,fa)) tf p in
+						make_call ctx ef (List.map fst el) ret p
+					in
+					(el,tf,mk_call)	:: candidates,failures
+				| _ ->
+					assert false
+			end
+		with Error (Call_error _,_) as err ->
+			candidates,err :: failures
+		end
+	) ([],[]) candidates in
+	let fail () = match List.rev failures with
+		| err :: _ -> raise err
+		| _ -> assert false
 	in
 	in
-	loop [] el args [] is_extern
+	if is_overload && ctx.com.config.pf_overload then begin match Codegen.Overloads.reduce_compatible candidates with
+		| [] -> fail()
+		| [el,tf,mk_call] -> List.map fst el,tf,mk_call
+		| _ -> error "Ambiguous overload" p
+	end else begin match List.rev candidates with
+		| [] -> fail()
+		| (el,tf,mk_call) :: _ -> List.map fst el,tf,mk_call
+	end
 
 
 let fast_enum_field e ef p =
 let fast_enum_field e ef p =
 	let et = mk (TTypeExpr (TEnumDecl e)) (TAnon { a_fields = PMap.empty; a_status = ref (EnumStatics e) }) p in
 	let et = mk (TTypeExpr (TEnumDecl e)) (TAnon { a_fields = PMap.empty; a_status = ref (EnumStatics e) }) p in
@@ -895,7 +873,7 @@ let make_call ctx e params t p =
 	try
 	try
 		let ethis, fname = (match e.eexpr with TField (ethis,f) -> ethis, field_name f | _ -> raise Exit) in
 		let ethis, fname = (match e.eexpr with TField (ethis,f) -> ethis, field_name f | _ -> raise Exit) in
 		let f, cl = (match follow ethis.etype with
 		let f, cl = (match follow ethis.etype with
-			| TInst (c,params) -> (try let _,_,f = Type.class_field c fname in f with Not_found -> raise Exit), Some c
+			| TInst (c,params) -> (try let _,_,f = Type.class_field c params fname in f with Not_found -> raise Exit), Some c
 			| TAnon a -> (try PMap.find fname a.a_fields with Not_found -> raise Exit), (match !(a.a_status) with Statics c -> Some c | _ -> None)
 			| TAnon a -> (try PMap.find fname a.a_fields with Not_found -> raise Exit), (match !(a.a_status) with Statics c -> Some c | _ -> None)
 			| _ -> raise Exit
 			| _ -> raise Exit
 		) in
 		) in
@@ -982,7 +960,7 @@ let rec acc_get ctx g p =
 		| _ -> assert false)
 		| _ -> assert false)
 	| AKInline (e,f,fmode,t) ->
 	| AKInline (e,f,fmode,t) ->
 		(* do not create a closure for static calls *)
 		(* do not create a closure for static calls *)
-		let cmode = (match fmode with FStatic _ -> fmode | FInstance (c,f) -> FClosure (Some c,f) | _ -> assert false) in
+		let cmode = (match fmode with FStatic _ -> fmode | FInstance (c,_,f) -> FClosure (Some c,f) | _ -> assert false) in
 		ignore(follow f.cf_type); (* force computing *)
 		ignore(follow f.cf_type); (* force computing *)
 		(match f.cf_expr with
 		(match f.cf_expr with
 		| None ->
 		| None ->
@@ -1106,8 +1084,8 @@ let field_access ctx mode f fmode t e p =
 			| MethMacro, MCall -> AKMacro (e,f)
 			| MethMacro, MCall -> AKMacro (e,f)
 			| _ , MGet ->
 			| _ , MGet ->
 				let cmode = (match fmode with
 				let cmode = (match fmode with
-					| FInstance(_, cf) | FStatic(_, cf) when Meta.has Meta.Generic cf.cf_meta -> display_error ctx "Cannot create closure on generic function" p; fmode
-					| FInstance (c,cf) -> FClosure (Some c,cf)
+					| FInstance(_, _, cf) | FStatic(_, cf) when Meta.has Meta.Generic cf.cf_meta -> display_error ctx "Cannot create closure on generic function" p; fmode
+					| FInstance (c,_,cf) -> FClosure (Some c,cf)
 					| FStatic _ | FEnum _ -> fmode
 					| FStatic _ | FEnum _ -> fmode
 					| FAnon f -> FClosure (None, f)
 					| FAnon f -> FClosure (None, f)
 					| FDynamic _ | FClosure _ -> assert false
 					| FDynamic _ | FClosure _ -> assert false
@@ -1285,7 +1263,7 @@ let rec type_ident_raise ?(imported_enums=true) ctx i p mode =
 				let cf = { (mk_field v.v_name v.v_type e.epos) with cf_params = params; cf_expr = Some e; cf_kind = Method MethInline } in
 				let cf = { (mk_field v.v_name v.v_type e.epos) with cf_params = params; cf_expr = Some e; cf_kind = Method MethInline } in
 				c.cl_extern <- true;
 				c.cl_extern <- true;
 				c.cl_fields <- PMap.add cf.cf_name cf PMap.empty;
 				c.cl_fields <- PMap.add cf.cf_name cf PMap.empty;
-				AKInline (mk (TConst TNull) (TInst (c,[])) p, cf, FInstance(c,cf), t)
+				AKInline (mk (TConst TNull) (TInst (c,[])) p, cf, FInstance(c,[],cf), t)
 			| _ ->
 			| _ ->
 				AKExpr (mk (TLocal v) t p))
 				AKExpr (mk (TLocal v) t p))
 		| _ ->
 		| _ ->
@@ -1293,8 +1271,8 @@ let rec type_ident_raise ?(imported_enums=true) ctx i p mode =
 	with Not_found -> try
 	with Not_found -> try
 		(* member variable lookup *)
 		(* member variable lookup *)
 		if ctx.curfun = FunStatic then raise Not_found;
 		if ctx.curfun = FunStatic then raise Not_found;
-		let c , t , f = class_field ctx ctx.curclass [] i p in
-		field_access ctx mode f (match c with None -> FAnon f | Some c -> FInstance (c,f)) t (get_this ctx p) p
+		let c , t , f = class_field ctx ctx.curclass (List.map snd ctx.curclass.cl_params) i p in
+		field_access ctx mode f (match c with None -> FAnon f | Some (c,tl) -> FInstance (c,tl,f)) t (get_this ctx p) p
 	with Not_found -> try
 	with Not_found -> try
 		(* lookup using on 'this' *)
 		(* lookup using on 'this' *)
 		if ctx.curfun = FunStatic then raise Not_found;
 		if ctx.curfun = FunStatic then raise Not_found;
@@ -1398,7 +1376,7 @@ and type_field ?(resume=false) ctx e i p mode =
 					with Unify_error l ->
 					with Unify_error l ->
 						display_error ctx "Field resolve has an invalid type" f.cf_pos;
 						display_error ctx "Field resolve has an invalid type" f.cf_pos;
 						display_error ctx (error_msg (Unify [Cannot_unify(tfield,texpect)])) f.cf_pos);
 						display_error ctx (error_msg (Unify [Cannot_unify(tfield,texpect)])) f.cf_pos);
-					AKExpr (make_call ctx (mk (TField (e,FInstance (c,f))) tfield p) [Codegen.type_constant ctx.com (String i) p] t p)
+					AKExpr (make_call ctx (mk (TField (e,FInstance (c,params,f))) tfield p) [Codegen.type_constant ctx.com (String i) p] t p)
 				end else
 				end else
 					AKExpr (mk (TField (e,FDynamic i)) t p)
 					AKExpr (mk (TField (e,FDynamic i)) t p)
 			| None ->
 			| None ->
@@ -1418,14 +1396,14 @@ and type_field ?(resume=false) ctx e i p mode =
 				| MCall, _ ->
 				| MCall, _ ->
 					()
 					()
 				| MGet,Var _
 				| MGet,Var _
-				| MSet,Var _ when (match c2 with Some { cl_extern = true; cl_path = ("flash" :: _,_) } -> true | _ -> false) ->
+				| MSet,Var _ when (match c2 with Some ({ cl_extern = true; cl_path = ("flash" :: _,_) }, _) -> true | _ -> false) ->
 					()
 					()
 				| _, Method _ ->
 				| _, Method _ ->
 					display_error ctx "Cannot create closure on super method" p
 					display_error ctx "Cannot create closure on super method" p
 				| _ ->
 				| _ ->
 					display_error ctx "Normal variables cannot be accessed with 'super', use 'this' instead" p);
 					display_error ctx "Normal variables cannot be accessed with 'super', use 'this' instead" p);
 			if not (can_access ctx c f false) && not ctx.untyped then display_error ctx ("Cannot access private field " ^ i) p;
 			if not (can_access ctx c f false) && not ctx.untyped then display_error ctx ("Cannot access private field " ^ i) p;
-			field_access ctx mode f (match c2 with None -> FAnon f | Some c -> FInstance (c,f)) (apply_params c.cl_params params t) e p
+			field_access ctx mode f (match c2 with None -> FAnon f | Some (c,tl) -> FInstance (c,tl,f)) (apply_params c.cl_params params t) e p
 		with Not_found -> try
 		with Not_found -> try
 			using_field ctx mode e i p
 			using_field ctx mode e i p
 		with Not_found -> try
 		with Not_found -> try
@@ -1655,8 +1633,8 @@ let unify_int ctx e k =
 		match follow t with
 		match follow t with
 		| TAnon a ->
 		| TAnon a ->
 			(try is_dynamic (PMap.find f a.a_fields).cf_type with Not_found -> false)
 			(try is_dynamic (PMap.find f a.a_fields).cf_type with Not_found -> false)
-		| TInst (c,pl) ->
-			(try is_dynamic (apply_params c.cl_params pl ((let _,t,_ = Type.class_field c f in t))) with Not_found -> false)
+		| TInst (c,tl) ->
+			(try is_dynamic (apply_params c.cl_params tl ((let _,t,_ = Type.class_field c tl f in t))) with Not_found -> false)
 		| _ ->
 		| _ ->
 			true
 			true
 	in
 	in
@@ -1718,7 +1696,7 @@ let type_generic_function ctx (e,cf) el ?(using_param=None) with_type p =
 		| WithTypeResume t -> (try unify_raise ctx ret t p with Error (Unify l,_) -> raise (WithTypeError(l,p)))
 		| WithTypeResume t -> (try unify_raise ctx ret t p with Error (Unify l,_) -> raise (WithTypeError(l,p)))
 		| _ -> ()
 		| _ -> ()
 	end;
 	end;
-	let el,_ = unify_call_args ctx None el args ret p false in
+	let el,_ = unify_call_args ctx el args ret p false false in
 	let el = match using_param with None -> el | Some e -> e :: el in
 	let el = match using_param with None -> el | Some e -> e :: el in
 	(try
 	(try
 		let gctx = Codegen.make_generic ctx cf.cf_params monos p in
 		let gctx = Codegen.make_generic ctx cf.cf_params monos p in
@@ -1764,8 +1742,8 @@ let type_generic_function ctx (e,cf) el ?(using_param=None) with_type p =
 			cf2
 			cf2
 		in
 		in
 		let e = if stat then type_type ctx c.cl_path p else e in
 		let e = if stat then type_type ctx c.cl_path p else e in
-		let e = acc_get ctx (field_access ctx MCall cf2 (if stat then FStatic (c,cf2) else FInstance (c,cf2)) cf2.cf_type e p) p in
-		(el,ret,e)
+		let e = acc_get ctx (field_access ctx MCall cf2 (if stat then FStatic (c,cf2) else FInstance (c,tl,cf2)) cf2.cf_type e p) p in
+		make_call ctx e el ret p
 	with Codegen.Generic_Exception (msg,p) ->
 	with Codegen.Generic_Exception (msg,p) ->
 		error msg p)
 		error msg p)
 
 
@@ -1801,7 +1779,7 @@ let rec type_binop ctx op e1 e2 is_assign_op with_type p =
 			check_assign ctx e1;
 			check_assign ctx e1;
 			(match e1.eexpr , e2.eexpr with
 			(match e1.eexpr , e2.eexpr with
 			| TLocal i1 , TLocal i2 when i1 == i2 -> error "Assigning a value to itself" p
 			| TLocal i1 , TLocal i2 when i1 == i2 -> error "Assigning a value to itself" p
-			| TField ({ eexpr = TConst TThis },FInstance (_,f1)) , TField ({ eexpr = TConst TThis },FInstance (_,f2)) when f1 == f2 ->
+			| TField ({ eexpr = TConst TThis },FInstance (_,_,f1)) , TField ({ eexpr = TConst TThis },FInstance (_,_,f2)) when f1 == f2 ->
 				error "Assigning a value to itself" p
 				error "Assigning a value to itself" p
 			| _ , _ -> ());
 			| _ , _ -> ());
 			mk (TBinop (op,e1,e2)) e1.etype p
 			mk (TBinop (op,e1,e2)) e1.etype p
@@ -1949,7 +1927,7 @@ let rec type_binop ctx op e1 e2 is_assign_op with_type p =
 				let std = type_type ctx ([],"Std") e.epos in
 				let std = type_type ctx ([],"Std") e.epos in
 				let acc = acc_get ctx (type_field ctx std "string" e.epos MCall) e.epos in
 				let acc = acc_get ctx (type_field ctx std "string" e.epos MCall) e.epos in
 				ignore(follow acc.etype);
 				ignore(follow acc.etype);
-				let acc = (match acc.eexpr with TField (e,FClosure (Some c,f)) -> { acc with eexpr = TField (e,FInstance (c,f)) } | _ -> acc) in
+				let acc = (match acc.eexpr with TField (e,FClosure (Some c,f)) -> { acc with eexpr = TField (e,FInstance (c,[],f)) } | _ -> acc) in
 				make_call ctx acc [e] ctx.t.tstring e.epos
 				make_call ctx acc [e] ctx.t.tstring e.epos
 			| KAbstract (a,tl) ->
 			| KAbstract (a,tl) ->
 				loop (Abstract.get_underlying_type a tl)
 				loop (Abstract.get_underlying_type a tl)
@@ -2949,7 +2927,7 @@ and type_expr ctx (e,p) (with_type:with_type) =
 		let el = e1 :: el in
 		let el = e1 :: el in
 		let v = gen_local ctx tmap in
 		let v = gen_local ctx tmap in
 		let ev = mk (TLocal v) tmap p in
 		let ev = mk (TLocal v) tmap p in
-		let ef = mk (TField(ev,FInstance(c,cf))) (tfun [tkey;tval] ctx.t.tvoid) p in
+		let ef = mk (TField(ev,FInstance(c,[tkey;tval],cf))) (tfun [tkey;tval] ctx.t.tvoid) p in
 		let el = ev :: List.fold_left (fun acc e -> match fst e with
 		let el = ev :: List.fold_left (fun acc e -> match fst e with
 			| EBinop(OpArrow,e1,e2) ->
 			| EBinop(OpArrow,e1,e2) ->
 				let e1,e2 = type_arrow e1 e2 in
 				let e1,e2 = type_arrow e1 e2 in
@@ -3045,7 +3023,7 @@ and type_expr ctx (e,p) (with_type:with_type) =
 					if fhasnext.cf_kind <> Method MethInline then raise Exit;
 					if fhasnext.cf_kind <> Method MethInline then raise Exit;
 					let tmp = gen_local ctx e1.etype in
 					let tmp = gen_local ctx e1.etype in
 					let eit = mk (TLocal tmp) e1.etype p in
 					let eit = mk (TLocal tmp) e1.etype p in
-					let ehasnext = make_call ctx (mk (TField (eit,FInstance (c, fhasnext))) (TFun([],ctx.t.tbool)) p) [] ctx.t.tbool p in
+					let ehasnext = make_call ctx (mk (TField (eit,FInstance (c, pl, fhasnext))) (TFun([],ctx.t.tbool)) p) [] ctx.t.tbool p in
 					let enext = mk (TVar (i,Some (make_call ctx (mk (TField (eit,FDynamic "next")) (TFun ([],pt)) p) [] pt p))) ctx.t.tvoid p in
 					let enext = mk (TVar (i,Some (make_call ctx (mk (TField (eit,FDynamic "next")) (TFun ([],pt)) p) [] pt p))) ctx.t.tvoid p in
 					let eblock = (match e2.eexpr with
 					let eblock = (match e2.eexpr with
 						| TBlock el -> { e2 with eexpr = TBlock (enext :: el) }
 						| TBlock el -> { e2 with eexpr = TBlock (enext :: el) }
@@ -3244,7 +3222,8 @@ and type_expr ctx (e,p) (with_type:with_type) =
 		let unify_constructor_call c params f ct = match follow ct with
 		let unify_constructor_call c params f ct = match follow ct with
 			| TFun (args,r) ->
 			| TFun (args,r) ->
 				(try
 				(try
-					fst (unify_call_args ctx (Some (TInst(c,params),f)) el args r p false)
+					let el,_,_ = unify_field_call ctx (FInstance(c,params,f)) el args r p false in
+					el
 				with Error (e,p) ->
 				with Error (e,p) ->
 					display_error ctx (error_msg e) p;
 					display_error ctx (error_msg e) p;
 					[])
 					[])
@@ -3267,14 +3246,16 @@ and type_expr ctx (e,p) (with_type:with_type) =
 			| mt ->
 			| mt ->
 				error ((s_type_path (t_infos mt).mt_path) ^ " cannot be constructed") p
 				error ((s_type_path (t_infos mt).mt_path) ^ " cannot be constructed") p
 		in
 		in
-		let ct = (match t with
-			| TAbstract (a,pl) ->
-				(match a.a_impl with
-				| None -> t
-				| Some c -> TInst (c,pl))
-			| _ -> t
-		) in
-		(match ct with
+		let build_constructor_call c tl =
+			let ct, f = get_constructor ctx c tl p in
+			if not (can_access ctx c f true || is_parent c ctx.curclass) && not ctx.untyped then display_error ctx "Cannot access private constructor" p;
+			(match f.cf_kind with
+			| Var { v_read = AccRequire (r,msg) } -> (match msg with Some msg -> error msg p | None -> error_require r p)
+			| _ -> ());
+			let el = unify_constructor_call c tl f ct in
+			el,f,ct
+		in
+		(match t with
 		| TInst ({cl_kind = KTypeParameter tl} as c,params) ->
 		| TInst ({cl_kind = KTypeParameter tl} as c,params) ->
 			if not (Typeload.is_generic_parameter ctx c) then error "Only generic type parameters can be constructed" p;
 			if not (Typeload.is_generic_parameter ctx c) then error "Only generic type parameters can be constructed" p;
 			let el = List.map (fun e -> type_expr ctx e Value) el in
 			let el = List.map (fun e -> type_expr ctx e Value) el in
@@ -3289,21 +3270,15 @@ and type_expr ctx (e,p) (with_type:with_type) =
 				| _ -> false
 				| _ -> false
 			) tl) then error (s_type_path c.cl_path ^ " does not have a constructor") p;
 			) tl) then error (s_type_path c.cl_path ^ " does not have a constructor") p;
 			mk (TNew (c,params,el)) t p
 			mk (TNew (c,params,el)) t p
-		| TInst (c,params) ->
-			let ct, f = get_constructor ctx c params p in
-			if not (can_access ctx c f true || is_parent c ctx.curclass) && not ctx.untyped then display_error ctx "Cannot access private constructor" p;
-			(match f.cf_kind with
-			| Var { v_read = AccRequire (r,msg) } -> (match msg with Some msg -> error msg p | None -> error_require r p)
-			| _ -> ());
-			let el = unify_constructor_call c params f ct in
-			(match c.cl_kind with
-			| KAbstractImpl a when not (Meta.has Meta.MultiType a.a_meta) ->
-				let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in
-				let e = mk (TTypeExpr (TClassDecl c)) ta p in
-				let e = mk (TField (e,(FStatic (c,f)))) ct p in
-				make_call ctx e el t p
-			| _ ->
-				mk (TNew (c,params,el)) t p)
+		| TAbstract({a_impl = Some c} as a,tl) when not (Meta.has Meta.MultiType a.a_meta) ->
+			let el,cf,ct = build_constructor_call c tl in
+			let ta = TAnon { a_fields = c.cl_statics; a_status = ref (Statics c) } in
+			let e = mk (TTypeExpr (TClassDecl c)) ta p in
+			let e = mk (TField (e,(FStatic (c,cf)))) ct p in
+			make_call ctx e el t p
+		| TInst (c,params) | TAbstract({a_impl = Some c},params) ->
+			let el,_,_ = build_constructor_call c params in
+			mk (TNew (c,params,el)) t p
 		| _ ->
 		| _ ->
 			error (s_type (print_context()) t ^ " cannot be constructed") p)
 			error (s_type (print_context()) t ^ " cannot be constructed") p)
 	| EUnop (op,flag,e) ->
 	| EUnop (op,flag,e) ->
@@ -3510,7 +3485,7 @@ and handle_display ctx e_ast iscall p =
 			if ctx.com.display = DMPosition then
 			if ctx.com.display = DMPosition then
 				raise (DisplayPosition [ef.ef_pos]);
 				raise (DisplayPosition [ef.ef_pos]);
 			ef.ef_meta <- (Meta.Usage,[],p) :: ef.ef_meta;
 			ef.ef_meta <- (Meta.Usage,[],p) :: ef.ef_meta;
-		| TField(_,(FAnon cf | FInstance (_,cf) | FStatic (_,cf) | FClosure (_,cf))) ->
+		| TField(_,(FAnon cf | FInstance (_,_,cf) | FStatic (_,cf) | FClosure (_,cf))) ->
 			handle_field cf;
 			handle_field cf;
 		| TLocal v ->
 		| TLocal v ->
 			v.v_meta <- (Meta.Usage,[],p) :: v.v_meta;
 			v.v_meta <- (Meta.Usage,[],p) :: v.v_meta;
@@ -3771,9 +3746,10 @@ and type_call ctx e el (with_type:with_type) p =
 		| None -> error "Current class does not have a super" p
 		| None -> error "Current class does not have a super" p
 		| Some (c,params) ->
 		| Some (c,params) ->
 			let ct, f = get_constructor ctx c params p in
 			let ct, f = get_constructor ctx c params p in
-			let el, _ = (match follow ct with
+			let el = (match follow ct with
 			| TFun (args,r) ->
 			| TFun (args,r) ->
-				unify_call_args ctx (Some (TInst(c,params),f)) el args r p false
+				let el,_,_ = unify_field_call ctx (FInstance(c,params,f)) el args r p false in
+				el
 			| _ ->
 			| _ ->
 				error "Constructor is not a function" p
 				error "Constructor is not a function" p
 			) in
 			) in
@@ -3784,11 +3760,6 @@ and type_call ctx e el (with_type:with_type) p =
 		def ()
 		def ()
 
 
 and build_call ctx acc el (with_type:with_type) p =
 and build_call ctx acc el (with_type:with_type) p =
-	let fopts t f = match follow t with
-		| (TInst (c,pl) as t) -> Some (t,f)
-		| (TAnon a) as t -> (match !(a.a_status) with Statics c -> Some (TInst(c,List.map snd c.cl_params),f) | _ -> Some (t,f))
-		| _ -> None
-	in
 	let push_this e =
 	let push_this e =
 		match e.eexpr with
 		match e.eexpr with
 			| TConst (TInt _ | TFloat _ | TString _ | TBool _) ->
 			| TConst (TInt _ | TFloat _ | TString _ | TBool _) ->
@@ -3800,19 +3771,19 @@ and build_call ctx acc el (with_type:with_type) p =
 	in
 	in
 	match acc with
 	match acc with
 	| AKInline (ethis,f,fmode,t) when Meta.has Meta.Generic f.cf_meta ->
 	| AKInline (ethis,f,fmode,t) when Meta.has Meta.Generic f.cf_meta ->
-		let el,t,e = type_generic_function ctx (ethis,f) el with_type p in
-		make_call ctx e el t p
+		type_generic_function ctx (ethis,f) el with_type p
 	| AKInline (ethis,f,fmode,t) ->
 	| AKInline (ethis,f,fmode,t) ->
-		let params, tfunc = (match follow t with
-			| TFun (args,r) -> unify_call_args ctx (fopts ethis.etype f) el args r p true
-			| _ -> error (s_type (print_context()) t ^ " cannot be called") p
-		) in
-		make_call ctx (mk (TField (ethis,fmode)) t p) params (match tfunc with TFun(_,r) -> r | _ -> assert false) p
+		(match follow t with
+			| TFun (args,r) ->
+				let _,_,mk_call = unify_field_call ctx fmode el args r p true in
+				mk_call ethis
+			| _ ->
+				error (s_type (print_context()) t ^ " cannot be called") p
+		)
 	| AKUsing (et,cl,ef,eparam) when Meta.has Meta.Generic ef.cf_meta ->
 	| AKUsing (et,cl,ef,eparam) when Meta.has Meta.Generic ef.cf_meta ->
 		(match et.eexpr with
 		(match et.eexpr with
 		| TField(ec,_) ->
 		| TField(ec,_) ->
-			let el,t,e = type_generic_function ctx (ec,ef) el ~using_param:(Some eparam) with_type p in
-			make_call ctx e el t p
+			type_generic_function ctx (ec,ef) el ~using_param:(Some eparam) with_type p
 		| _ -> assert false)
 		| _ -> assert false)
 	| AKUsing (et,cl,ef,eparam) ->
 	| AKUsing (et,cl,ef,eparam) ->
 		begin match ef.cf_kind with
 		begin match ef.cf_kind with
@@ -3833,7 +3804,7 @@ and build_call ctx acc el (with_type:with_type) p =
 				| TFun ((_,_,t1) :: args,r) ->
 				| TFun ((_,_,t1) :: args,r) ->
 					unify ctx tthis t1 eparam.epos;
 					unify ctx tthis t1 eparam.epos;
 					let ef = prepare_using_field ef in
 					let ef = prepare_using_field ef in
-					begin match unify_call_args ctx (Some (TInst(cl,[]),ef)) el args r p (ef.cf_kind = Method MethInline) with
+					begin match unify_call_args ctx el args r p (ef.cf_kind = Method MethInline) (is_forced_inline (Some cl) ef) with
 					| el,TFun(args,r) -> el,args,r,(if is_abstract_impl_call then eparam else Codegen.AbstractCast.check_cast ctx t1 eparam eparam.epos)
 					| el,TFun(args,r) -> el,args,r,(if is_abstract_impl_call then eparam else Codegen.AbstractCast.check_cast ctx t1 eparam eparam.epos)
 					| _ -> assert false
 					| _ -> assert false
 					end
 					end
@@ -3898,36 +3869,39 @@ and build_call ctx acc el (with_type:with_type) p =
 	| AKExpr e ->
 	| AKExpr e ->
 		let rec loop t = match follow t with
 		let rec loop t = match follow t with
 		| TFun (args,r) ->
 		| TFun (args,r) ->
-			let fopts = (match acc with
-				| AKExpr {eexpr = TField(e, (FStatic (_,f) | FInstance(_,f) | FAnon(f)))} ->
-					fopts e.etype f
-				| _ ->
-					None
-			) in
-			(match fopts,acc with
-				| Some (_,cf),AKExpr({eexpr = TField(e,_)}) when Meta.has Meta.Generic cf.cf_meta ->
-					type_generic_function ctx (e,cf) el with_type p
+			begin match e.eexpr with
+				| TField(e1,fa) when not (match fa with FEnum _ -> true | _ -> false) ->
+					begin match fa with
+						| FInstance(_,_,cf) | FStatic(_,cf) when Meta.has Meta.Generic cf.cf_meta ->
+							type_generic_function ctx (e1,cf) el with_type p
+						| _ ->
+							let _,_,mk_call = unify_field_call ctx fa el args r p false in
+							mk_call e1
+					end
 				| _ ->
 				| _ ->
-					let el, tfunc = unify_call_args ctx fopts el args r p false in
-					el,(match tfunc with TFun(_,r) -> r | _ -> assert false), {e with etype = tfunc})
+					let el, tfunc = unify_call_args ctx el args r p false false in
+					let r = match tfunc with TFun(_,r) -> r | _ -> assert false in
+					mk (TCall ({e with etype = tfunc},el)) r p
+			end
 		| TAbstract(a,tl) when Meta.has Meta.Callable a.a_meta ->
 		| TAbstract(a,tl) when Meta.has Meta.Callable a.a_meta ->
 			loop (Abstract.get_underlying_type a tl)
 			loop (Abstract.get_underlying_type a tl)
 		| TMono _ ->
 		| TMono _ ->
 			let t = mk_mono() in
 			let t = mk_mono() in
 			let el = List.map (fun e -> type_expr ctx e Value) el in
 			let el = List.map (fun e -> type_expr ctx e Value) el in
 			unify ctx (tfun (List.map (fun e -> e.etype) el) t) e.etype e.epos;
 			unify ctx (tfun (List.map (fun e -> e.etype) el) t) e.etype e.epos;
-			el, t, e
+			mk (TCall (e,el)) t p
 		| t ->
 		| t ->
 			let el = List.map (fun e -> type_expr ctx e Value) el in
 			let el = List.map (fun e -> type_expr ctx e Value) el in
-			el, (if t == t_dynamic then
+			let t = if t == t_dynamic then
 				t_dynamic
 				t_dynamic
 			else if ctx.untyped then
 			else if ctx.untyped then
 				mk_mono()
 				mk_mono()
 			else
 			else
-				error (s_type (print_context()) e.etype ^ " cannot be called") e.epos), e
+				error (s_type (print_context()) e.etype ^ " cannot be called") e.epos
+			in
+			mk (TCall (e,el)) t p
 		in
 		in
-		let el , t, e = loop e.etype in
-		mk (TCall (e,el)) t p
+		loop e.etype
 
 
 (* ---------------------------------------------------------------------- *)
 (* ---------------------------------------------------------------------- *)
 (* FINALIZATION *)
 (* FINALIZATION *)
@@ -4609,7 +4583,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 			incr index;
 			incr index;
 			(EArray ((EArrayDecl [e],p),(EConst (Int (string_of_int (!index))),p)),p)
 			(EArray ((EArrayDecl [e],p),(EConst (Int (string_of_int (!index))),p)),p)
 		) el in
 		) el in
-		let elt, _ = unify_call_args mctx (Some (TInst(mclass,[]),mfield)) constants (List.map fst eargs) t_dynamic p false in
+		let elt, _ = unify_call_args mctx constants (List.map fst eargs) t_dynamic p false false in
 		List.iter (fun f -> f()) (!todo);
 		List.iter (fun f -> f()) (!todo);
 		List.map2 (fun (_,ise) e ->
 		List.map2 (fun (_,ise) e ->
 			let e, et = (match e.eexpr with
 			let e, et = (match e.eexpr with
@@ -4696,7 +4670,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 
 
 let call_macro ctx path meth args p =
 let call_macro ctx path meth args p =
 	let mctx, (margs,_,mclass,mfield), call = load_macro ctx path meth p in
 	let mctx, (margs,_,mclass,mfield), call = load_macro ctx path meth p in
-	let el, _ = unify_call_args mctx (Some (TInst(mclass,[]),mfield)) args margs t_dynamic p false in
+	let el, _ = unify_call_args mctx args margs t_dynamic p false false in
 	call (List.map (fun e -> try Interp.make_const e with Exit -> error "Parameter should be a constant" e.epos) el)
 	call (List.map (fun e -> try Interp.make_const e with Exit -> error "Parameter should be a constant" e.epos) el)
 
 
 let call_init_macro ctx e =
 let call_init_macro ctx e =