Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default type parameters #10518

Merged
merged 13 commits into from
Jan 4, 2022
2 changes: 1 addition & 1 deletion src/codegen/codegen.ml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ let fix_override com c f fd =
have to detect this case and change the variable (issue #2712). *)
begin match follow v.v_type with
| TInst({cl_kind = KTypeParameter [tc]} as cp,_) when com.platform = Flash ->
if List.mem_assoc (snd cp.cl_path) c.cl_params then raise (Unify_error [])
if List.exists (fun (name,_,_) -> name = (snd cp.cl_path)) c.cl_params then raise (Unify_error [])
| _ ->
()
end;
Expand Down
3 changes: 3 additions & 0 deletions src/codegen/dotnet.ml
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ let convert_ilmethod ctx p is_interface m is_explicit_impl =
tp_name = "M" ^ string_of_int t.tnumber,null_pos;
tp_params = [];
tp_constraints = None;
tp_default = None;
tp_meta = [];
}
) m.mtypes in
Expand Down Expand Up @@ -643,6 +644,7 @@ let convert_delegate ctx p ilcls =
tp_name = ("T" ^ string_of_int t.tnumber),null_pos;
tp_params = [];
tp_constraints = None;
tp_default = None;
tp_meta = [];
}
) ilcls.ctypes in
Expand Down Expand Up @@ -816,6 +818,7 @@ let convert_ilclass ctx p ?(delegate=false) ilcls = match ilcls.csuper with
tp_name = "T" ^ string_of_int p.tnumber,null_pos;
tp_params = [];
tp_constraints = None;
tp_default = None;
tp_meta = [];
}) ilcls.ctypes
in
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/gencommon/castDetect.ml
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ let handle_type_parameter gen e e1 ef ~clean_ef ~overloads_cast_to_base f elist

(* this function will receive the original function argument, the applied function argument and the original function parameters. *)
(* from this info, it will infer the applied tparams for the function *)
let infer_params pos (original_args:((string * bool * t) list * t)) (applied_args:((string * bool * t) list * t)) (params:(string * t) list) calls_parameters_explicitly : tparams =
let infer_params pos (original_args:((string * bool * t) list * t)) (applied_args:((string * bool * t) list * t)) (params:(string * t * t option) list) calls_parameters_explicitly : tparams =
match params with
| [] -> []
| _ ->
Expand Down
18 changes: 9 additions & 9 deletions src/codegen/gencommon/closuresToClass.ml
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ let rec get_type_params acc t =
get_type_params acc ( Abstract.get_underlying_type a pl)
| TAnon a ->
PMap.fold (fun cf acc ->
let params = List.map (fun (_,t) -> match follow t with
let params = List.map (fun (_,t,_) -> match follow t with
| TInst(c,_) -> c
| _ -> die "" __LOC__) cf.cf_params
in
Expand Down Expand Up @@ -396,7 +396,7 @@ let configure gen ft =
in

(*let cltypes = List.map (fun cl -> (snd cl.cl_path, TInst(map_param cl, []) )) tparams in*)
let cltypes = List.map (fun cl -> (snd cl.cl_path, TInst(cl, []) )) tparams in
let cltypes = List.map (fun cl -> (snd cl.cl_path, TInst(cl, []), None )) tparams in

(* create a new class that extends abstract function class, with a ctor implementation that will setup all captured variables *)
let cfield = match gen.gcurrent_classfield with
Expand Down Expand Up @@ -426,7 +426,7 @@ let configure gen ft =

let mk_this v pos =
{
(mk_field_access gen { eexpr = TConst TThis; etype = TInst(cls, List.map snd cls.cl_params); epos = pos } v.v_name pos)
(mk_field_access gen { eexpr = TConst TThis; etype = TInst(cls, extract_param_types cls.cl_params); epos = pos } v.v_name pos)
with etype = v.v_type
}
in
Expand Down Expand Up @@ -476,9 +476,9 @@ let configure gen ft =
eexpr = TCall({
eexpr = TField({
eexpr = TConst TThis;
etype = TInst(cls, List.map snd cls.cl_params);
etype = TInst(cls, extract_param_types cls.cl_params);
epos = pos;
}, FInstance(cls, List.map snd cls.cl_params, cf));
}, FInstance(cls, extract_param_types cls.cl_params, cf));
etype = cf.cf_type;
epos = pos;
}, List.map (fun (v,_) -> mk_local v pos) tfunc.tf_args);
Expand Down Expand Up @@ -617,8 +617,8 @@ let configure gen ft =
| TInst(c,_), TInst(c2,_) -> c == c2
| _ -> false
in
let passoc = List.map2 (fun (_,t) m -> t,m) types monos in
let cltparams = List.map (fun (_,t) ->
let passoc = List.map2 (fun (_,t,_) m -> t,m) types monos in
let cltparams = List.map (fun (_,t,_) ->
try
snd (List.find (fun (t2,_) -> same_cl t t2) passoc)
with | Not_found -> t) cls.cl_params
Expand Down Expand Up @@ -899,7 +899,7 @@ struct

let map_base_classfields cl map_fn =
let pos = cl.cl_pos in
let this_t = TInst(cl,List.map snd cl.cl_params) in
let this_t = TInst(cl,extract_param_types cl.cl_params) in
let this = { eexpr = TConst(TThis); etype = this_t; epos = pos } in
let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in

Expand Down Expand Up @@ -1091,7 +1091,7 @@ struct
loop arity []
in

let this = mk (TConst TThis) (TInst (cl, List.map snd cl.cl_params)) pos in
let this = mk (TConst TThis) (TInst (cl, extract_param_types cl.cl_params)) pos in
let mk_this field t = { (mk_field_access gen this field pos) with etype = t } in

let mk_invoke_switch i api =
Expand Down
8 changes: 4 additions & 4 deletions src/codegen/gencommon/enumToClass.ml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ struct
| _ -> ());
let c_types =
if handle_type_params then
List.map (fun (s,t) -> (s, TInst (map_param (get_cl_t t), []))) en.e_params
List.map (fun (s,t,def) -> (s, TInst (map_param (get_cl_t t), []),def)) en.e_params
else
[]
in
Expand All @@ -121,13 +121,13 @@ struct
| TFun(params,ret) ->
let dup_types =
if handle_type_params then
List.map (fun (s,t) -> (s, TInst (map_param (get_cl_t t), []))) en.e_params
List.map (fun (s,t,def) -> (s, TInst (map_param (get_cl_t t), []), def)) en.e_params
else
[]
in

let ef_type =
let fn, types = if handle_type_params then snd, dup_types else (fun _ -> t_dynamic), en.e_params in
let fn, types = if handle_type_params then extract_param_type, dup_types else (fun _ -> t_dynamic), en.e_params in
let t = apply_params en.e_params (List.map fn types) ef.ef_type in
apply_params ef.ef_params (List.map fn ef.ef_params) t
in
Expand All @@ -144,7 +144,7 @@ struct
eexpr = TFunction({
tf_args = tf_args;
tf_type = ret;
tf_expr = mk_block ( mk_return { eexpr = TNew(cl,List.map snd dup_types, [make_int gen.gcon.basic old_i pos; arr_decl] ); etype = TInst(cl, List.map snd dup_types); epos = pos } );
tf_expr = mk_block ( mk_return { eexpr = TNew(cl,extract_param_types dup_types, [make_int gen.gcon.basic old_i pos; arr_decl] ); etype = TInst(cl, extract_param_types dup_types); epos = pos } );
});
etype = ef_type;
epos = pos
Expand Down
16 changes: 8 additions & 8 deletions src/codegen/gencommon/fixOverrides.ml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ let run ~explicit_fn_name ~get_vmtype gen =
) c.cl_ordered_fields;
md
| TClassDecl c when not (has_class_flag c CExtern) ->
let this = { eexpr = TConst TThis; etype = TInst(c,List.map snd c.cl_params); epos = c.cl_pos } in
let this = { eexpr = TConst TThis; etype = TInst(c,extract_param_types c.cl_params); epos = c.cl_pos } in
(* look through all interfaces, and try to find a type that applies exactly *)
let rec loop_iface (iface:tclass) itl =
List.iter (fun (s,stl) -> loop_iface s (List.map (apply_params iface.cl_params itl) stl)) iface.cl_implements;
Expand All @@ -81,19 +81,19 @@ let run ~explicit_fn_name ~get_vmtype gen =
Overloads.same_overload_args ~get_vmtype ftype t f f2
) overloads
| _ :: _ ->
(match field_access gen (TInst(c, List.map snd c.cl_params)) f.cf_name with
(match field_access gen (TInst(c, extract_param_types c.cl_params)) f.cf_name with
| FClassField(_,_,_,f2,false,t,_) -> t,f2 (* if it's not an overload, all functions should have the same signature *)
| _ -> raise Not_found)
| [] -> raise Not_found
in
replace_mono t2;
(* if we find a function with the exact type of real_ftype, it means this interface has already been taken care of *)
if not (type_iseq (get_real_fun gen (apply_params f2.cf_params (List.map snd f.cf_params) t2)) real_ftype) then begin
if not (type_iseq (get_real_fun gen (apply_params f2.cf_params (extract_param_types f.cf_params) t2)) real_ftype) then begin
(match f.cf_kind with | Method (MethNormal | MethInline) -> () | _ -> raise Not_found);
let t2 = get_real_fun gen t2 in
if List.length f.cf_params <> List.length f2.cf_params then raise Not_found;
replace_mono t2;
match follow (apply_params f2.cf_params (List.map snd f.cf_params) t2), follow real_ftype with
match follow (apply_params f2.cf_params (extract_param_types f.cf_params) t2), follow real_ftype with
| TFun(a1,r1), TFun(a2,r2) when not implement_explicitly && not (type_iseq r1 r2) && Overloads.same_overload_args ~get_vmtype real_ftype t2 f f2 ->
(* different return types are the trickiest cases to deal with *)
(* check for covariant return type *)
Expand All @@ -107,7 +107,7 @@ let run ~explicit_fn_name ~get_vmtype gen =
(* we only have to worry about non-covariant issues *)
if not is_covariant then begin
(* override return type and cast implemented function *)
let args, newr = match follow t2, follow (apply_params f.cf_params (List.map snd f2.cf_params) real_ftype) with
let args, newr = match follow t2, follow (apply_params f.cf_params (extract_param_types f2.cf_params) real_ftype) with
| TFun(a,_), TFun(_,r) -> a,r
| _ -> Globals.die "" __LOC__
in
Expand All @@ -133,7 +133,7 @@ let run ~explicit_fn_name ~get_vmtype gen =
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 field = { eexpr = TField(this, FInstance(c,List.map snd c.cl_params,f2)); etype = TFun(a1,r1); epos = p } in
let field = { eexpr = TField(this, FInstance(c,extract_param_types c.cl_params,f2)); etype = TFun(a1,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 is_void = ExtType.is_void r2 in
Expand Down Expand Up @@ -221,8 +221,8 @@ let run ~explicit_fn_name ~get_vmtype gen =
eexpr = TCall(
{
eexpr = TField(
{ eexpr = TConst TThis; etype = TInst(c, List.map snd c.cl_params); epos = p },
FInstance(c,List.map snd c.cl_params,f));
{ eexpr = TConst TThis; etype = TInst(c, extract_param_types c.cl_params); epos = p },
FInstance(c,extract_param_types c.cl_params,f));
etype = f.cf_type;
epos = p
},
Expand Down
6 changes: 3 additions & 3 deletions src/codegen/gencommon/gencommon.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ let follow_module follow_func md = match md with
| TClassDecl _
| TEnumDecl _
| TAbstractDecl _ -> md
| TTypeDecl tdecl -> match (follow_func (TType(tdecl, List.map snd tdecl.t_params))) with
| TTypeDecl tdecl -> match (follow_func (TType(tdecl, extract_param_types tdecl.t_params))) with
| TInst(cl,_) -> TClassDecl cl
| TEnum(e,_) -> TEnumDecl e
| TType(t,_) -> TTypeDecl t
Expand Down Expand Up @@ -1188,7 +1188,7 @@ let find_first_declared_field gen orig_cl ?get_vmtype ?exact_field field =
loop_cl (depth+1) sup tl tlch
) c.cl_implements
in
loop_cl 0 orig_cl (List.map snd orig_cl.cl_params) (List.map snd orig_cl.cl_params);
loop_cl 0 orig_cl (extract_param_types orig_cl.cl_params) (extract_param_types orig_cl.cl_params);
match !chosen with
| None ->
None
Expand Down Expand Up @@ -1296,7 +1296,7 @@ let field_access_esp gen t field = match field with
in
let p = match follow (run_follow gen t) with
| TInst(_,p) -> p
| _ -> List.map snd cl.cl_params
| _ -> extract_param_types cl.cl_params
in
FClassField(cl,p,cl,cf,static,cf.cf_type,cf.cf_type)
| _ -> field_access gen t (field_name field)
Expand Down
6 changes: 3 additions & 3 deletions src/codegen/gencommon/initFunction.ml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ let handle_class com cl =
let is_var = match cf.cf_kind with Var _ -> true | _ -> false in
(match cf.cf_expr, cf.cf_params with
| Some e, [] ->
let var = mk (TField ((mk (TConst TThis) (TInst (cl, List.map snd cl.cl_params)) cf.cf_pos), FInstance(cl, List.map snd cl.cl_params, cf))) cf.cf_type cf.cf_pos in
let var = mk (TField ((mk (TConst TThis) (TInst (cl, extract_param_types cl.cl_params)) cf.cf_pos), FInstance(cl, extract_param_types cl.cl_params, cf))) cf.cf_type cf.cf_pos in
let ret = binop Ast.OpAssign var e cf.cf_type cf.cf_pos in
cf.cf_expr <- None;
let is_override = has_class_field_flag cf CfOverride in
Expand All @@ -139,7 +139,7 @@ let handle_class com cl =
| Some e, _ ->
let params = List.map (fun _ -> t_dynamic) cf.cf_params in
let fn = apply_params cf.cf_params params in
let var = mk (TField ((mk (TConst TThis) (TInst (cl, List.map snd cl.cl_params)) cf.cf_pos), FInstance(cl, List.map snd cl.cl_params, cf))) cf.cf_type cf.cf_pos in
let var = mk (TField ((mk (TConst TThis) (TInst (cl, extract_param_types cl.cl_params)) cf.cf_pos), FInstance(cl, extract_param_types cl.cl_params, cf))) cf.cf_type cf.cf_pos in
let rec change_expr e =
Type.map_expr_type (change_expr) fn (fun v -> v.v_type <- fn v.v_type; v) e
in
Expand Down Expand Up @@ -173,7 +173,7 @@ let handle_class com cl =
ctor
| None ->
try
let sctor, sup, stl = OverloadingConstructor.prev_ctor cl (List.map snd cl.cl_params) in
let sctor, sup, stl = OverloadingConstructor.prev_ctor cl (extract_param_types cl.cl_params) in
let ctor = OverloadingConstructor.clone_ctors com sctor sup stl cl in
cl.cl_constructor <- Some ctor;
ctor
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/gencommon/interfaceVarsDeleteModf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ let configure gen =
cl.cl_ordered_fields <- fields;

List.iter (fun cf ->
match field_access gen (TInst(cl,List.map snd cl.cl_params)) cf.cf_name with
match field_access gen (TInst(cl,extract_param_types cl.cl_params)) cf.cf_name with
| FNotFound | FDynamicField _ ->
cl.cl_ordered_fields <- cf :: cl.cl_ordered_fields;
cl.cl_fields <- PMap.add cf.cf_name cf cl.cl_fields
Expand Down
22 changes: 11 additions & 11 deletions src/codegen/gencommon/overloadingConstructor.ml
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,21 @@ let create_static_ctor com ~empty_ctor_expr cl ctor follow_type =
| false ->
let static_ctor_name = make_static_ctor_name cl in
(* create the static constructor *)
let ctor_types = List.map (fun (s,t) -> (s, TInst(map_param (get_cl_t t), []))) cl.cl_params in
let ctor_type_params = List.map snd ctor_types in
List.iter (function (_,TInst(c,[])) -> (
let ctor_types = List.map (fun (s,t,d) -> (s, TInst(map_param (get_cl_t t), []),d)) cl.cl_params in
let ctor_type_params = extract_param_types ctor_types in
List.iter (function (_,TInst(c,[]),_) -> (
match c.cl_kind with
| KTypeParameter (hd :: tail) ->
let before = hd :: tail in
let after = List.map (apply_params cl.cl_params ctor_type_params) (before) in
c.cl_kind <- KTypeParameter(after)
| _ -> ())
| _ -> ()) ctor_types;
let me = alloc_var "__hx_this" (TInst(cl, List.map snd ctor_types)) in
let me = alloc_var "__hx_this" (TInst(cl, extract_param_types ctor_types)) in
add_var_flag me VCaptured;

let fn_args, _ = get_fun ctor.cf_type in
let ctor_params = List.map snd ctor_types in
let ctor_params = extract_param_types ctor_types in
let fn_type = TFun((me.v_name,false, me.v_type) :: List.map (fun (n,o,t) -> (n,o,apply_params cl.cl_params ctor_params t)) fn_args, com.basic.tvoid) in
let cur_tf_args = match ctor.cf_expr with
| Some { eexpr = TFunction(tf) } -> tf.tf_args
Expand Down Expand Up @@ -223,10 +223,10 @@ let create_static_ctor com ~empty_ctor_expr cl ctor follow_type =
eexpr = TField(
Texpr.Builder.make_static_this cl p,
FStatic(cl, static_ctor));
etype = apply_params static_ctor.cf_params (List.map snd cl.cl_params) static_ctor.cf_type;
etype = apply_params static_ctor.cf_params (extract_param_types cl.cl_params) static_ctor.cf_type;
epos = p
},
[{ eexpr = TConst TThis; etype = TInst(cl, List.map snd cl.cl_params); epos = p }]
[{ eexpr = TConst TThis; etype = TInst(cl, extract_param_types cl.cl_params); epos = p }]
@ el_args
);
etype = com.basic.tvoid;
Expand All @@ -250,7 +250,7 @@ let clone_ctors com ctor sup stl cl =
let super_call =
{
eexpr = TCall(
{ eexpr = TConst TSuper; etype = TInst(cl, List.map snd cl.cl_params); epos = ctor.cf_pos },
{ eexpr = TConst TSuper; etype = TInst(cl, extract_param_types cl.cl_params); epos = ctor.cf_pos },
List.map (fun (v,_) -> mk_local v ctor.cf_pos) tf_args);
etype = com.basic.tvoid;
epos = ctor.cf_pos;
Expand Down Expand Up @@ -328,7 +328,7 @@ let init com (empty_ctor_type : t) (empty_ctor_expr : texpr) (follow_type : t ->
ctor
| None ->
try
let sctor, sup, stl = prev_ctor cl (List.map snd cl.cl_params) in
let sctor, sup, stl = prev_ctor cl (extract_param_types cl.cl_params) in
(* we'll make constructors that will only call super() *)
let ctor = clone_ctors com sctor sup stl cl in
cl.cl_constructor <- Some ctor;
Expand Down Expand Up @@ -383,12 +383,12 @@ let init com (empty_ctor_type : t) (empty_ctor_expr : texpr) (follow_type : t ->
| Some (sup,_) ->
try
ignore (get_last_empty sup);
let esuper = mk (TConst TSuper) (TInst (cl, List.map snd cl.cl_params)) cl.cl_pos in
let esuper = mk (TConst TSuper) (TInst (cl, extract_param_types cl.cl_params)) cl.cl_pos in
[mk (TCall (esuper, [empty_ctor_expr])) basic.tvoid cl.cl_pos]
with Not_found ->
try
(* super type is native: find super constructor with least arguments *)
let sctor, sup, stl = prev_ctor cl (List.map snd cl.cl_params) in
let sctor, sup, stl = prev_ctor cl (extract_param_types cl.cl_params) in
let rec loop remaining (best,n) =
match remaining with
| [] -> best
Expand Down
Loading