Pārlūkot izejas kodu

expand all constraints for now

Simon Krajewski 3 gadi atpakaļ
vecāks
revīzija
da4db7d949

+ 1 - 1
src/codegen/gencommon/castDetect.ml

@@ -289,7 +289,7 @@ let do_unsafe_cast gen from_t to_t e	=
 			| _ -> raise Not_found
 	in
 	match gen.gfollow#run_f from_t, gen.gfollow#run_f to_t with
-	| TInst({ cl_kind = KTypeParameter tl },_), t2 when List.exists (fun t -> unifies t t2) tl ->
+	| TInst({ cl_kind = KTypeParameter tl },_), t2 when List.exists (fun t -> unifies t t2) (expand_constraints tl) ->
 		mk_cast to_t (mk_cast t_dynamic e)
 	| from_t, to_t when gen.gspecial_needs_cast to_t from_t ->
 		mk_cast to_t e

+ 1 - 1
src/codegen/gencommon/closuresToClass.ml

@@ -279,7 +279,7 @@ let traverse gen ?tparam_anon_decl ?tparam_anon_acc (handle_anon_func:texpr->tfu
 let rec get_type_params acc t =
 	match t with
 		| TInst(( { cl_kind = KTypeParameter constraints } as cl), []) ->
-			let params = List.fold_left get_type_params acc constraints in
+			let params = List.fold_left get_type_params acc (expand_constraints constraints) in
 			List.filter (fun t -> not (List.memq t acc)) (cl :: params) @ acc;
 		| TFun (params,tret) ->
 			List.fold_left get_type_params acc ( tret :: List.map (fun (_,_,t) -> t) params )

+ 2 - 2
src/codegen/gencommon/dynamicFieldAccess.ml

@@ -59,7 +59,7 @@ let priority = solve_deps name [DAfter DynamicOperators.priority]
 let configure gen (is_dynamic:texpr->Type.tfield_access->bool) (change_expr:texpr->texpr->string->texpr option->bool->texpr) (call_expr:texpr->texpr->string->texpr list->texpr) =
 	let is_nondynamic_tparam fexpr f = match follow fexpr.etype with
 		| TInst({ cl_kind = KTypeParameter(tl) }, _) ->
-			List.exists (fun t -> not (is_dynamic { fexpr with etype = t } f)) tl
+			List.exists (fun t -> not (is_dynamic { fexpr with etype = t } f)) (expand_constraints tl)
 		| _ -> false
 	in
 
@@ -69,7 +69,7 @@ let configure gen (is_dynamic:texpr->Type.tfield_access->bool) (change_expr:texp
 		| TField(fexpr, f) when is_nondynamic_tparam fexpr f ->
 			(match follow fexpr.etype with
 				| TInst( ({ cl_kind = KTypeParameter(tl) } as tp_cl), tp_tl) ->
-					let t = apply_params tp_cl.cl_params tp_tl (List.find (fun t -> not (is_dynamic { fexpr with etype = t } f)) tl) in
+					let t = apply_params tp_cl.cl_params tp_tl (List.find (fun t -> not (is_dynamic { fexpr with etype = t } f)) (expand_constraints tl)) in
 					{ e with eexpr = TField(mk_cast t (run fexpr), f) }
 				| _ -> Globals.die "" __LOC__)
 

+ 1 - 1
src/codegen/gencommon/overloadingConstructor.ml

@@ -119,7 +119,7 @@ let create_static_ctor com ~empty_ctor_expr cl ctor follow_type =
 		List.iter (function (_,TInst(c,[])) -> (
 			match c.cl_kind with
 			| KTypeParameter (hd :: tail) ->
-				let before = hd :: tail in
+				let before = expand_constraints (hd :: tail) in
 				let after = List.map (apply_params cl.cl_params ctor_type_params) (before) in
 				c.cl_kind <- KTypeParameter(after)
 			| _ -> ())

+ 1 - 1
src/codegen/overloads.ml

@@ -15,7 +15,7 @@ let same_overload_args ?(get_vmtype) t1 t2 f1 f2 =
 			| (n1,t1) :: params1,(n2,t2) :: params2 ->
 				let constraints_equal t1 t2 = match follow t1,t2 with
 					| TInst({cl_kind = KTypeParameter tl1},_),TInst({cl_kind = KTypeParameter tl2},_) ->
-						Ast.safe_for_all2 f_eq tl1 tl2
+						Ast.safe_for_all2 f_eq (expand_constraints tl1) (expand_constraints tl2)
 					| _ ->
 						false
 				in

+ 1 - 1
src/context/abstractCast.ml

@@ -124,7 +124,7 @@ let find_array_access_raise ctx a pl e1 e2o p =
 			let check_constraints () =
 				List.iter2 (fun m (name,t) -> match follow t with
 					| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
-						List.iter (fun tc -> match follow m with TMono _ -> raise (Unify_error []) | _ -> Type.unify m (map tc) ) constr
+						List.iter (fun tc -> match follow m with TMono _ -> raise (Unify_error []) | _ -> Type.unify m (map tc) ) (expand_constraints constr)
 					| _ -> ()
 				) monos cf.cf_params;
 			in

+ 2 - 2
src/context/display/displayFields.ml

@@ -58,7 +58,7 @@ let collect_static_extensions ctx items e p =
 				let e = TyperBase.unify_static_extension ctx {e with etype = dup e.etype} t p in
 				List.iter2 (fun m (name,t) -> match follow t with
 					| TInst ({ cl_kind = KTypeParameter constr },_) when constr <> [] ->
-						List.iter (fun tc -> unify_raise ctx m (map tc) e.epos) constr
+						List.iter (fun tc -> unify_raise ctx m (map tc) e.epos) (expand_constraints constr)
 					| _ -> ()
 				) monos f.cf_params;
 				if not (can_access ctx c f true) || follow e.etype == t_dynamic && follow t != t_dynamic then
@@ -159,7 +159,7 @@ let collect ctx e_ast e dk with_type p =
 			fold_constraints items (Monomorph.classify_down_constraints m)
 		| TInst ({cl_kind = KTypeParameter tl},_) ->
 			(* Type parameters can access the fields of their constraints *)
-			List.fold_left (fun acc t -> loop acc t) items tl
+			List.fold_left (fun acc t -> loop acc t) items (expand_constraints tl)
 		| TInst(c0,tl) ->
 			(* For classes, browse the hierarchy *)
 			let fields = TClass.get_all_fields c0 tl in

+ 1 - 1
src/context/typecore.ml

@@ -549,7 +549,7 @@ let rec can_access ctx c cf stat =
 	(* access is also allowed of we access a type parameter which is constrained to our (base) class *)
 	|| (match c.cl_kind with
 		| KTypeParameter tl ->
-			List.exists (fun t -> match follow t with TInst(c,_) -> loop c | _ -> false) tl
+			List.exists (fun t -> match follow t with TInst(c,_) -> loop c | _ -> false) (expand_constraints tl)
 		| _ -> false)
 	|| (Meta.has Meta.PrivateAccess ctx.meta)
 

+ 1 - 1
src/core/display/completionItem.ml

@@ -803,7 +803,7 @@ let to_json ctx index item =
 				"TypeParameter",jobject [
 					"name",jstring (snd c.cl_path);
 					"meta",generate_metadata ctx c.cl_meta;
-					"constraints",jlist (generate_type ctx) tl;
+					"constraints",jlist (generate_type ctx) (expand_constraints tl);
 				]
 			| _ -> die "" __LOC__
 			end

+ 2 - 2
src/core/json/genjson.ml

@@ -277,7 +277,7 @@ and generate_type_path_with_params ctx mpath tpath tl meta =
 
 and generate_type_parameter ctx (s,t) =
 	let generate_constraints () = match follow t with
-		| TInst({cl_kind = KTypeParameter tl},_) -> generate_types ctx tl
+		| TInst({cl_kind = KTypeParameter tl},_) -> generate_types ctx (expand_constraints tl)
 		| _ -> die "" __LOC__
 	in
 	jobject [
@@ -600,7 +600,7 @@ let generate_class ctx c =
 	let generate_class_kind ck =
 		let ctor,args = match ck with
 		| KNormal -> "KNormal",None
-		| KTypeParameter tl -> "KTypeParameter",Some (generate_types ctx tl)
+		| KTypeParameter tl -> "KTypeParameter",Some (generate_types ctx (expand_constraints tl))
 		| KExpr e -> "KExpr",Some (generate_expr ctx e)
 		| KGeneric -> "KGeneric",None
 		| KGenericInstance(c,tl) -> "KGenericInstance",Some (generate_type_path_with_params ctx c.cl_module.m_path c.cl_path tl c.cl_meta)

+ 16 - 2
src/core/tFunctions.ml

@@ -630,13 +630,27 @@ let tconst_to_const = function
 	| TThis -> Ident "this"
 	| TSuper -> Ident "super"
 
+let expand_constraints tl =
+	let rec loop acc tl = match tl with
+		| [] ->
+			acc
+		| t :: tl ->
+			begin match follow t with
+			| TIntersection(t1,t2) ->
+				loop (loop acc [t1]) (t2 :: tl)
+			| _ ->
+				loop (t :: acc) tl
+			end
+	in
+	loop [] tl
+
 let has_ctor_constraint c = match c.cl_kind with
 	| KTypeParameter tl ->
 		List.exists (fun t -> match follow t with
 			| TAnon a when PMap.mem "new" a.a_fields -> true
 			| TAbstract({a_path=["haxe"],"Constructible"},_) -> true
 			| _ -> false
-		) tl;
+		) (expand_constraints tl);
 	| _ -> false
 
 (* ======= Field utility ======= *)
@@ -713,7 +727,7 @@ let rec raw_class_field build_type c tl i =
 					in
 					loop2 t
 			in
-			loop tl
+			loop (expand_constraints tl)
 		| _ ->
 			if not (has_class_flag c CInterface) then raise Not_found;
 			(*

+ 6 - 6
src/core/tUnification.ml

@@ -266,7 +266,7 @@ module Monomorph = struct
 			let mono = create () in
 			begin match follow t with
 				| TInst ({ cl_kind = KTypeParameter constr; cl_path = path },_) when constr <> [] ->
-					DynArray.add checks (mono,constr,s_type_path path)
+					DynArray.add checks (mono,(expand_constraints constr),s_type_path path)
 				| _ ->
 					()
 			end;
@@ -709,7 +709,7 @@ let rec unify (uctx : unification_context) a b =
 				| TInst (cs,tls) -> loop cs (List.map (apply_params c.cl_params tl) tls)
 				| TAbstract(aa,tl) -> unifies_to uctx a b aa tl
 				| _ -> false
-			) pl
+			) (expand_constraints pl)
 			| _ -> false)
 		in
 		if not (loop c1 tl1) then error [cannot_unify a b]
@@ -733,7 +733,7 @@ let rec unify (uctx : unification_context) a b =
 		if PMap.is_empty an.a_fields then (match c.cl_kind with
 			| KTypeParameter pl ->
 				(* one of the constraints must unify with { } *)
-				if not (List.exists (fun t -> match follow t with TInst _ | TAnon _ -> true | _ -> false) pl) then error [cannot_unify a b]
+				if not (List.exists (fun t -> match follow t with TInst _ | TAnon _ -> true | _ -> false) (expand_constraints pl)) then error [cannot_unify a b]
 			| _ -> ());
 		ignore(c.cl_build());
 		(try
@@ -835,7 +835,7 @@ let rec unify (uctx : unification_context) a b =
 			begin match c.cl_kind with
 				| KTypeParameter tl ->
 					(* type parameters require an equal Constructible constraint *)
-					if not (List.exists (fun t -> match follow t with TAbstract({a_path = ["haxe"],"Constructible"},[t2]) -> type_iseq uctx t1 t2 | _ -> false) tl) then error [cannot_unify a b]
+					if not (List.exists (fun t -> match follow t with TAbstract({a_path = ["haxe"],"Constructible"},[t2]) -> type_iseq uctx t1 t2 | _ -> false) (expand_constraints tl)) then error [cannot_unify a b]
 				| _ ->
 					let _,t,cf = class_field c tl "new" in
 					if not (has_class_field_flag cf CfPublic) then error [invalid_visibility "new"];
@@ -893,7 +893,7 @@ let rec unify (uctx : unification_context) a b =
 		if not (List.exists (fun t ->
 			let t = apply_params c.cl_params pl t in
 			try unify uctx t b; true with Unify_error _ -> false
-		) ctl) then unify_from uctx a b bb tl
+		) (expand_constraints ctl)) then unify_from uctx a b bb tl
 	| _, TAbstract (bb,tl) ->
 		unify_from uctx a b bb tl
 	| _,TIntersection(t1,t2) ->
@@ -1145,7 +1145,7 @@ module UnifyMinT = struct
 		let rec loop t = (match t with
 			| TInst(cl, params) ->
 				(match cl.cl_kind with
-				| KTypeParameter tl -> List.iter loop tl
+				| KTypeParameter tl -> List.iter loop (expand_constraints tl)
 				| _ -> ());
 				List.iter (fun (ic, ip) ->
 					let t = apply_params cl.cl_params params (TInst (ic,ip)) in

+ 1 - 0
src/generators/gencs.ml

@@ -2021,6 +2021,7 @@ let generate con =
 							List.fold_left (fun acc (name, t) ->
 								match run_follow gen t with
 									| TInst({cl_kind = KTypeParameter constraints}, _) when constraints <> [] ->
+										let constraints = expand_constraints constraints in
 										(* base class should come before interface constraints *)
 										let base_class_constraints = ref [] in
 										let other_constraints = List.fold_left (fun acc t ->

+ 2 - 2
src/generators/genhl.ml

@@ -437,7 +437,7 @@ let rec to_type ?tref ctx t =
 					| TInst (c,_) as t when not (has_class_flag c CInterface) -> to_type ?tref ctx t
 					| _ -> loop tl
 			in
-			loop tl
+			loop (expand_constraints tl)
 		| _ -> class_type ~tref ctx c pl false)
 	| TAbstract ({a_path = [],"Null"},[t1]) ->
 		let t = to_type ?tref ctx t1 in
@@ -2137,7 +2137,7 @@ and eval_expr ctx e =
 					(match follow rt with
 					| TInst({ cl_kind = KTypeParameter tl },_) ->
 						(* don't allow if we have a constraint virtual, see hxbit.Serializer.getRef *)
-						not (List.exists (fun t -> match to_type ctx t with HVirtual _ -> true | _ -> false) tl)
+						not (List.exists (fun t -> match to_type ctx t with HVirtual _ -> true | _ -> false) (expand_constraints tl))
 					| _ -> false)
 				| _ ->
 					false

+ 1 - 1
src/generators/genjvm.ml

@@ -2536,7 +2536,7 @@ class tclass_to_jvm gctx c = object(self)
 			| TInst({cl_kind = KTypeParameter tl},_) ->
 				List.map (fun t ->
 					get_boxed_type (jsignature_of_type gctx t)
-				 ) tl
+				 ) (expand_constraints tl)
 			| _ ->
 				[]
 			in

+ 1 - 1
src/generators/genlua.ml

@@ -273,7 +273,7 @@ let mk_mr_select com e ecall name =
 (* from genphp *)
 let rec is_string_type t =
     match follow t with
-    | TInst ({cl_kind = KTypeParameter constraints}, _) -> List.exists is_string_type constraints
+    | TInst ({cl_kind = KTypeParameter constraints}, _) -> List.exists is_string_type (expand_constraints constraints)
     | TInst ({cl_path = ([], "String")}, _) -> true
     | TAnon a ->
         (match !(a.a_status) with

+ 1 - 1
src/generators/genswf9.ml

@@ -239,7 +239,7 @@ let rec type_id ctx t =
 	| TInst (c,_) ->
 		(match c.cl_kind with
 		| KTypeParameter l ->
-			(match l with
+			(match expand_constraints l with
 			| [t] -> type_id ctx t
 			| _ -> type_path ctx ([],"Object"))
 		| _ ->

+ 1 - 1
src/macro/macroApi.ml

@@ -985,7 +985,7 @@ and encode_method_kind m =
 and encode_class_kind k =
 	let tag, pl = (match k with
 		| KNormal -> 0, []
-		| KTypeParameter pl -> 1, [encode_tparams pl]
+		| KTypeParameter pl -> 1, [encode_tparams (expand_constraints pl)]
 		| KModuleFields m -> 2, [encode_string (s_type_path m.m_path)]
 		| KExpr e -> 3, [encode_expr e]
 		| KGeneric -> 4, []

+ 2 - 2
src/optimization/dce.ml

@@ -226,7 +226,7 @@ and mark_t dce p t =
 		| TInst({cl_kind = KTypeParameter tl} as c,pl) ->
 			if not (Meta.has Meta.Used c.cl_meta) then begin
 				c.cl_meta <- (mk_used_meta c.cl_pos) :: c.cl_meta;
-				List.iter (mark_t dce p) tl;
+				List.iter (mark_t dce p) (expand_constraints tl);
 			end;
 			List.iter (mark_t dce p) pl
 		| TInst(c,pl) ->
@@ -353,7 +353,7 @@ and field dce c n stat =
 				| t :: tl ->
 					loop tl
 			in
-			loop tl
+			loop (expand_constraints tl)
 		| _ -> raise Not_found
 	with Not_found ->
 		if dce.debug then prerr_endline ("[DCE] Field " ^ n ^ " not found on " ^ (s_type_path c.cl_path)) else ())

+ 1 - 1
src/optimization/inline.ml

@@ -238,7 +238,7 @@ let inline_default_config cf t =
 			c.cl_params @ ct, pl @ cpl
 	in
 	let rec loop t = match follow t with
-		| TInst({cl_kind = KTypeParameter tl},_) -> List.fold_left (fun (params',tl') (params,tl) -> (params @ params',tl @ tl')) ([],[]) (List.map loop tl)
+		| TInst({cl_kind = KTypeParameter tl},_) -> List.fold_left (fun (params',tl') (params,tl) -> (params @ params',tl @ tl')) ([],[]) (List.map loop (expand_constraints tl))
 		| TInst (c,pl) -> get_params c pl
 		| _ -> ([],[])
 	in

+ 1 - 1
src/typing/fields.ml

@@ -329,7 +329,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) =
 					type_field_by_list (fun t -> match follow t with
 						| TAbstract _ -> type_field_by_e type_field_by_type (mk_cast e t p);
 						| _ -> raise Not_found
-					) tl
+					) (expand_constraints tl)
 				| _ -> raise Not_found
 			with Not_found ->
 				type_field_by_interfaces e c

+ 2 - 2
src/typing/generic.ml

@@ -180,7 +180,7 @@ let rec build_generic ctx c p tl =
 		match follow t with
 		| TInst (c2,tl) ->
 			(match c2.cl_kind with
-			| KTypeParameter tl ->
+			| KTypeParameter _ ->
 				if not (TypeloadCheck.is_generic_parameter ctx c2) && has_ctor_constraint c2 then
 					error "Type parameters with a constructor cannot be used non-generically" p;
 				recurse := true
@@ -263,7 +263,7 @@ let rec build_generic ctx c p tl =
 			(* Type parameter constraints are substituted here. *)
 			cf_new.cf_params <- List.rev_map (fun (s,t) -> match follow t with
 				| TInst({cl_kind = KTypeParameter tl1} as c,_) ->
-					let tl1 = List.map (generic_substitute_type gctx) tl1 in
+					let tl1 = List.map (generic_substitute_type gctx) (expand_constraints tl1) in
 					c.cl_kind <- KTypeParameter tl1;
 					s,t
 				| _ -> die "" __LOC__

+ 2 - 2
src/typing/operators.ml

@@ -162,9 +162,9 @@ let rec classify t =
 	| TAbstract ({ a_path = [],"Int" },[]) -> KInt
 	| TAbstract ({ a_path = [],"Float" },[]) -> KFloat
 	| TAbstract (a,[]) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) a.a_to -> KNumParam t
-	| TInst ({ cl_kind = KTypeParameter ctl },_) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) ctl -> KNumParam t
+	| TInst ({ cl_kind = KTypeParameter ctl },_) when List.exists (fun t -> match classify t with KInt | KFloat -> true | _ -> false) (expand_constraints ctl) -> KNumParam t
 	| TAbstract (a,[]) when List.exists (fun t -> match classify t with KString -> true | _ -> false) a.a_to -> KStrParam t
-	| TInst ({ cl_kind = KTypeParameter ctl },_) when List.exists (fun t -> match classify t with KString -> true | _ -> false) ctl -> KStrParam t
+	| TInst ({ cl_kind = KTypeParameter ctl },_) when List.exists (fun t -> match classify t with KString -> true | _ -> false) (expand_constraints ctl) -> KStrParam t
 	| TMono r when r.tm_type = None -> KUnk
 	| TDynamic _ -> KDyn
 	| _ -> KOther

+ 1 - 1
src/typing/typer.ml

@@ -995,7 +995,7 @@ and type_new ctx path el with_type force_inline p =
 	try begin match Abstract.follow_with_forward_ctor t with
 	| TInst ({cl_kind = KTypeParameter tl} as c,params) ->
 		if not (TypeloadCheck.is_generic_parameter ctx c) then error "Only generic type parameters can be constructed" p;
- 		begin match get_constructible_constraint ctx tl p with
+ 		begin match get_constructible_constraint ctx (expand_constraints tl) p with
 		| None ->
 			raise_error (No_constructor (TClassDecl c)) p
 		| Some(tl,tr) ->

+ 1 - 1
src/typing/typerBase.ml

@@ -166,7 +166,7 @@ let get_constructible_constraint ctx tl p =
 			| TAbstract({a_path = ["haxe"],"Constructible"},[t1]) ->
 				Some (extract_function t1)
 			| TInst({cl_kind = KTypeParameter tl1},_) ->
-				begin match loop tl1 with
+				begin match loop (expand_constraints tl1) with
 				| None -> loop tl
 				| Some _ as t -> t
 				end

+ 2 - 2
src/typing/typerDisplay.ml

@@ -232,7 +232,7 @@ let rec handle_signature_display ctx e_ast with_type =
 					| TAbstract({a_path = ["haxe"],"Constructible"},[t]) -> t
 					| _ -> loop tl
 			in
-			[loop tl,None,PMap.empty]
+			[loop (expand_constraints tl),None,PMap.empty]
 		| TInst (c,tl) | TAbstract({a_impl = Some c},tl) ->
 			Display.merge_core_doc ctx (TClassDecl c);
 			let fa = get_constructor_access c tl p in
@@ -579,7 +579,7 @@ let handle_display ctx e_ast dk mode with_type =
 						false
 					end
 				end
-			| ITTypeParameter {cl_kind = KTypeParameter tl} when get_constructible_constraint ctx tl null_pos <> None ->
+			| ITTypeParameter {cl_kind = KTypeParameter tl} when get_constructible_constraint ctx (expand_constraints tl) null_pos <> None ->
 				true
 			| _ -> false
 		) r.fitems in