Browse Source

[typer] turn TDynamic argument into an option

Simon Krajewski 2 years ago
parent
commit
a404ec6ec2

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

@@ -185,7 +185,9 @@ let rec type_eq gen param a b =
 			) l1 l2
 		with
 			Unify_error l -> Type.error (cannot_unify a b :: l))
-	| TDynamic a , TDynamic b ->
+	| TDynamic None , TDynamic None ->
+		()
+	| TDynamic (Some a) , TDynamic (Some b) ->
 		type_eq gen param a b
 	| TAnon a1, TAnon a2 ->
 		(try

+ 4 - 2
src/codegen/gencommon/closuresToClass.ml

@@ -283,8 +283,10 @@ let rec get_type_params acc t =
 			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 )
-		| TDynamic t ->
-			(match t with | TDynamic _ -> acc | _ -> get_type_params acc t)
+		| TDynamic None ->
+			acc
+		| TDynamic (Some t) ->
+			get_type_params acc t
 		| TAbstract (a, pl) when not (Meta.has Meta.CoreType a.a_meta) ->
 				get_type_params acc ( Abstract.get_underlying_type a pl)
 		| TAnon a ->

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

@@ -1291,7 +1291,7 @@ let rec field_access gen (t:t) (field:string) : (tfield_access) =
 		| _ when PMap.mem field gen.gbase_class_fields ->
 			let cf = PMap.find field gen.gbase_class_fields in
 			FClassField(gen.gclasses.cl_dyn, [t_dynamic], gen.gclasses.cl_dyn, cf, false, cf.cf_type, cf.cf_type)
-		| TDynamic t -> FDynamicField t
+		| TDynamic t -> FDynamicField (match t with None -> t_dynamic | Some t -> t)
 		| TMono _ -> FDynamicField t_dynamic
 		| _ -> FNotFound
 

+ 2 - 1
src/codegen/genxml.ml

@@ -122,7 +122,8 @@ let rec gen_type ?(values=None) t =
 		) args in
 		node "f" (("a",names) :: values) (List.map gen_type (args @ [r]))
 	| TAnon a -> node "a" [] (pmap (fun f -> gen_field [] { f with cf_flags = unset_flag f.cf_flags (int_of_class_field_flag CfPublic) }) a.a_fields)
-	| TDynamic t2 -> node "d" [] (if t == t2 then [] else [gen_type t2])
+	| TDynamic None -> node "d" [] []
+	| TDynamic (Some t2) -> node "d" [] [gen_type t2]
 	| TLazy f -> gen_type (lazy_type f)
 
 and gen_type_decl n t pl =

+ 4 - 2
src/core/display/completionItem.ml

@@ -506,8 +506,10 @@ module CompletionType = struct
 					ct_fields = PMap.fold (fun cf acc -> afield cf :: acc) an.a_fields [];
 					ct_status = !(an.a_status);
 				}
-			| TDynamic t ->
-				CTDynamic (if t == t_dynamic then None else Some (from_type PMap.empty t))
+			| TDynamic None ->
+				CTDynamic None
+			| TDynamic (Some t) ->
+				CTDynamic (Some (from_type PMap.empty t))
 		in
 		from_type values t
 end

+ 4 - 2
src/core/error.ml

@@ -188,8 +188,10 @@ module BetterErrors = struct
 					let fl = PMap.fold (fun f acc -> ((if Meta.has Meta.Optional f.cf_meta then " ?" else " ") ^ f.cf_name) :: acc) a.a_fields [] in
 					"{" ^ String.concat "," fl ^ " }"
 			end
-		| TDynamic t2 ->
-			"Dynamic" ^ s_type_params ctx (if t == t2 then [] else [t2])
+		| TDynamic None ->
+			"Dynamic"
+		| TDynamic (Some t2) ->
+			"Dynamic" ^ s_type_params ctx [t2]
 		| TLazy f ->
 			s_type ctx (lazy_type f)
 

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

@@ -219,7 +219,8 @@ let rec generate_type ctx t =
 			let t = lazy_type f in
 			(* return_partial_type := false; *)
 			loop t
-		| TDynamic t -> "TDynamic",Some (if t == t_dynamic then jnull else generate_type ctx t)
+		| TDynamic None -> "TDynamic", Some jnull
+		| TDynamic (Some t) -> "TDynamic",Some (generate_type ctx t)
 		| TInst(c,tl) -> "TInst",Some (generate_type_path_with_params ctx c.cl_module.m_path c.cl_path tl c.cl_meta)
 		| TEnum(en,tl) -> "TEnum",Some (generate_type_path_with_params ctx en.e_module.m_path en.e_path tl en.e_meta)
 		| TType(td,tl) -> "TType",Some (generate_type_path_with_params ctx td.t_module.m_path td.t_path tl td.t_meta)

+ 13 - 10
src/core/tFunctions.ml

@@ -91,7 +91,7 @@ let null t p = mk (TConst TNull) t p
 
 let mk_mono() = TMono (!monomorph_create_ref ())
 
-let rec t_dynamic = TDynamic t_dynamic
+let t_dynamic = TDynamic None
 
 let mk_anon ?fields status =
 	let fields = match fields with Some fields -> fields | None -> PMap.empty in
@@ -294,8 +294,10 @@ let map loop t =
 		let ft = lazy_type f in
 		let ft2 = loop ft in
 		if ft == ft2 then t else ft2
-	| TDynamic t2 ->
-		if t == t2 then	t else TDynamic (loop t2)
+	| TDynamic None ->
+		t
+	| TDynamic (Some t2) ->
+		TDynamic (Some (loop t2))
 
 let iter loop t =
 	match t with
@@ -321,8 +323,10 @@ let iter loop t =
 	| TLazy f ->
 		let ft = lazy_type f in
 		loop ft
-	| TDynamic t2 ->
-		if t != t2 then	loop t2
+	| TDynamic None ->
+		()
+	| TDynamic (Some t2) ->
+		loop t2
 
 let duplicate t =
 	let monos = ref [] in
@@ -458,11 +462,10 @@ let apply_params ?stack cparams params t =
 				t
 			else
 				ft2
-		| TDynamic t2 ->
-			if t == t2 then
-				t
-			else
-				TDynamic (loop t2)
+		| TDynamic None ->
+			t
+		| TDynamic (Some t2) ->
+			TDynamic (Some (loop t2))
 	in
 	loop t
 

+ 4 - 2
src/core/tOther.ml

@@ -86,8 +86,10 @@ module TExprToExpr = struct
 					} :: acc
 				) a.a_fields [])
 			end
-		| (TDynamic t2) as t ->
-			tpath ([],"Dynamic") ([],"Dynamic") (if t == t_dynamic then [] else [tparam t2])
+		| TDynamic None ->
+			tpath ([],"Dynamic") ([],"Dynamic") []
+		| TDynamic (Some t2) ->
+			tpath ([],"Dynamic") ([],"Dynamic") [tparam t2]
 		| TLazy f ->
 			convert_type (lazy_type f)
 

+ 4 - 2
src/core/tPrinting.ml

@@ -87,8 +87,10 @@ let rec s_type ctx t =
 				let fl = PMap.fold (fun f acc -> ((if Meta.has Meta.Optional f.cf_meta then " ?" else " ") ^ f.cf_name ^ " : " ^ s_type ctx f.cf_type) :: acc) a.a_fields [] in
 				"{" ^ String.concat "," fl ^ " }"
 		end
-	| TDynamic t2 ->
-		"Dynamic" ^ s_type_params ctx (if t == t2 then [] else [t2])
+	| TDynamic None ->
+		"Dynamic"
+	| TDynamic (Some t2) ->
+		"Dynamic" ^ s_type_params ctx [t2]
 	| TLazy f ->
 		s_type ctx (lazy_type f)
 

+ 1 - 1
src/core/tType.ml

@@ -51,7 +51,7 @@ type t =
 	| TType of tdef * tparams
 	| TFun of tsignature
 	| TAnon of tanon
-	| TDynamic of t
+	| TDynamic of t option
 	| TLazy of tlazy ref
 	| TAbstract of tabstract * tparams
 

+ 31 - 25
src/core/tUnification.ml

@@ -296,11 +296,10 @@ let rec link e a b =
 		| TEnum (_,tl) -> List.exists loop tl
 		| TInst (_,tl) | TType (_,tl) | TAbstract (_,tl) -> List.exists loop tl
 		| TFun (tl,t) -> List.exists (fun (_,_,t) -> loop t) tl || loop t
-		| TDynamic t2 ->
-			if t == t2 then
-				false
-			else
-				loop t2
+		| TDynamic None ->
+			false
+		| TDynamic (Some t2) ->
+			loop t2
 		| TLazy f ->
 			loop (lazy_type f)
 		| TAnon a ->
@@ -508,7 +507,9 @@ let rec type_eq uctx a b =
 		(match t.tm_type with
 		| None -> if param = EqCoreType || not (link t b a) then error [cannot_unify a b]
 		| Some t -> type_eq uctx a t)
-	| TDynamic a , TDynamic b ->
+	| TDynamic None, TDynamic None ->
+		()
+	| TDynamic (Some a) , TDynamic (Some b) ->
 		type_eq uctx a b
 	| _ , _ when a == t_dynamic && param = EqBothDynamic ->
 		()
@@ -835,30 +836,34 @@ let rec unify (uctx : unification_context) a b =
 		with Not_found ->
 			error [has_no_field a "new"]
 		end
-	| TDynamic t , _ ->
-		if t == a && uctx.allow_dynamic_to_cast then
+	| TDynamic None , _ ->
+		if uctx.allow_dynamic_to_cast then
 			()
-		else (match b with
-		| TDynamic t2 ->
-			if t2 != b then
+		else begin match b with
+			| TDynamic None ->
+				()
+			| _ ->
+				error [cannot_unify a b]
+		end
+	| TDynamic (Some t1) , _ ->
+		begin match b with
+		| TDynamic None ->
+			()
+		| TDynamic (Some t2) ->
+			if t2 != t1 then
 				(try
-					type_eq {uctx with equality_kind = EqRightDynamic} t t2
+					type_eq {uctx with equality_kind = EqRightDynamic} t1 t2
 				with
 					Unify_error l -> error (cannot_unify a b :: l));
 		| TAbstract(bb,tl) ->
 			unify_from uctx a b bb tl
 		| _ ->
-			error [cannot_unify a b])
-	| _ , TDynamic t ->
-		if t == b then
-			()
-		else (match a with
-		| TDynamic t2 ->
-			if t2 != a then
-				(try
-					type_eq {uctx with equality_kind = EqRightDynamic} t t2
-				with
-					Unify_error l -> error (cannot_unify a b :: l));
+			error [cannot_unify a b]
+		end
+	| _ , TDynamic None ->
+		()
+	| _ , TDynamic (Some t1) ->
+		begin match a with
 		| TAnon an ->
 			(try
 				(match !(an.a_status) with
@@ -866,7 +871,7 @@ let rec unify (uctx : unification_context) a b =
 				| _ -> ());
 				PMap.iter (fun _ f ->
 					try
-						type_eq uctx (field_type f) t
+						type_eq uctx (field_type f) t1
 					with Unify_error l ->
 						error (invalid_field f.cf_name :: l)
 				) an.a_fields
@@ -875,7 +880,8 @@ let rec unify (uctx : unification_context) a b =
 		| TAbstract(aa,tl) ->
 			unify_to uctx a b aa tl
 		| _ ->
-			error [cannot_unify a b])
+			error [cannot_unify a b]
+		end
 	| TAbstract (aa,tl), _  ->
 		unify_to uctx a b aa tl
 	| TInst ({ cl_kind = KTypeParameter ctl } as c,pl), TAbstract (bb,tl) ->

+ 4 - 5
src/filters/filters.ml

@@ -802,11 +802,10 @@ let update_cache_dependencies com t =
 		end
 		| TLazy f ->
 			check_t m (lazy_type f)
-		| TDynamic t ->
-			if t == t_dynamic then
-				()
-			else
-				check_t m t
+		| TDynamic None ->
+			()
+		| TDynamic (Some t) ->
+			check_t m t
 	in
 	let rec check_field m cf =
 		check_t m cf.cf_type;

+ 4 - 2
src/generators/genhxold.ml

@@ -104,8 +104,10 @@ let generate_type com t =
 			"{" ^ String.concat ", " fields ^ "}"
 		| TLazy f ->
 			stype (lazy_type f)
-		| TDynamic t2 ->
-			if t == t2 then "Dynamic" else "Dynamic<" ^ stype t2 ^ ">"
+		| TDynamic None ->
+			"Dynamic"
+		| TDynamic (Some t2) ->
+			"Dynamic<" ^ stype t2 ^ ">"
 		| TFun ([],ret) ->
 			"() -> " ^ ftype ret
 		| TFun (args,ret) ->

+ 1 - 1
src/generators/genswf.ml

@@ -84,7 +84,7 @@ let build_dependencies t =
 		| TAnon a ->
 			PMap.iter (fun _ f -> add_type_rec (t::l) f.cf_type) a.a_fields
 		| TDynamic t2 ->
-			add_type_rec (t::l) t2;
+			add_type_rec (t::l) (match t2 with None -> t_dynamic | Some t2 -> t2);
 		| TLazy f ->
 			add_type_rec l (lazy_type f)
 		| TMono r ->

+ 5 - 6
src/macro/macroApi.ml

@@ -1207,11 +1207,10 @@ and encode_type t =
 			4 , [encode_array pl; encode_type ret]
 		| TAnon a ->
 			5, [encode_ref a encode_tanon (fun() -> "<anonymous>")]
-		| TDynamic tsub as t ->
-			if t == t_dynamic then
-				6, [vnull]
-			else
-				6, [encode_type tsub]
+		| TDynamic None ->
+			6, [vnull]
+		| TDynamic (Some tsub) ->
+			6, [encode_type tsub]
 		| TLazy f ->
 			loop (lazy_type f)
 		| TAbstract (a, pl) ->
@@ -1255,7 +1254,7 @@ and decode_type t =
 	| 3, [t; pl] -> TType (decode_ref t, List.map decode_type (decode_array pl))
 	| 4, [pl; r] -> TFun (List.map (fun p -> decode_string (field p "name"), decode_bool (field p "opt"), decode_type (field p "t")) (decode_array pl), decode_type r)
 	| 5, [a] -> TAnon (decode_ref a)
-	| 6, [t] -> if t = vnull then t_dynamic else TDynamic (decode_type t)
+	| 6, [t] -> if t = vnull then t_dynamic else TDynamic (Some (decode_type t))
 	| 7, [f] -> TLazy (decode_lazytype f)
 	| 8, [a; pl] -> TAbstract (decode_ref a, List.map decode_type (decode_array pl))
 	| _ -> raise Invalid_expr

+ 5 - 8
src/optimization/dce.ml

@@ -312,12 +312,9 @@ let rec to_string dce t = match t with
 		| _ -> ())
 	| TLazy f ->
 		to_string dce (lazy_type f)
-	| TDynamic t ->
-		if t == t_dynamic then
-			()
-		else
-			to_string dce t
-	| TEnum _ | TFun _ | TAnon _ | TAbstract({a_impl = None},_) ->
+	| TDynamic (Some t) ->
+		to_string dce t
+	| TEnum _ | TFun _ | TAnon _ | TAbstract({a_impl = None},_) | TDynamic None ->
 		(* if we to_string these it does not imply that we need all its sub-types *)
 		()
 
@@ -585,11 +582,11 @@ and expr dce e =
 		check_and_add_feature dce "unsafe_string_concat";
 		expr dce e1;
 		expr dce e2;
-	| TArray(({etype = TDynamic t} as e1),e2) when t == t_dynamic ->
+	| TArray(({etype = TDynamic None} as e1),e2) ->
 		check_and_add_feature dce "dynamic_array_read";
 		expr dce e1;
 		expr dce e2;
-	| TBinop( (OpAssign | OpAssignOp _), ({eexpr = TArray({etype = TDynamic t},_)} as e1), e2) when t == t_dynamic ->
+	| TBinop( (OpAssign | OpAssignOp _), ({eexpr = TArray({etype = TDynamic None},_)} as e1), e2) ->
 		check_and_add_feature dce "dynamic_array_write";
 		expr dce e1;
 		expr dce e2;

+ 1 - 1
src/typing/fields.ml

@@ -518,7 +518,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) =
 				typing_error ("Cannot access static field " ^ i ^ " from a class instance") pfield;
 			)
 		| TDynamic t ->
-			AKExpr (mk (TField (e,FDynamic i)) t p)
+			AKExpr (mk (TField (e,FDynamic i)) (match t with None -> t_dynamic | Some t -> t) p)
 		| TAbstract (a,tl) ->
 			(try
 				if not (TypeFieldConfig.allow_resolve cfg) then raise Not_found;

+ 4 - 2
src/typing/generic.ml

@@ -190,8 +190,10 @@ let set_type_parameter_dependencies mg tl =
 			| Some t -> loop t)
 		| TLazy f ->
 			loop (lazy_type f);
-		| TDynamic t2 ->
-			if t == t2 then () else loop t2
+		| TDynamic None ->
+			()
+		| TDynamic (Some t2) ->
+			loop t2
 		| TAnon a ->
 			PMap.iter (fun _ f -> loop f.cf_type) a.a_fields
 		| TFun (args,ret) ->

+ 1 - 1
src/typing/typeload.ml

@@ -335,7 +335,7 @@ let rec load_instance' ctx (t,p) allow_no_params =
 		end else if path = ([],"Dynamic") then
 			match t.tparams with
 			| [] -> t_dynamic
-			| [TPType t] -> TDynamic (load_complex_type ctx true t)
+			| [TPType t] -> TDynamic (Some (load_complex_type ctx true t))
 			| _ -> typing_error "Too many parameters for Dynamic" p
 		else begin
 			let is_java_rest = ctx.com.platform = Java && is_extern in

+ 1 - 1
src/typing/typeloadCheck.ml

@@ -603,7 +603,7 @@ module Inheritance = struct
 				| TDynamic t ->
 					if c.cl_dynamic <> None then typing_error "Cannot have several dynamics" p;
 					if not (has_class_flag c CExtern) then display_error ctx.com "In haxe 4, implements Dynamic is only supported on externs" p;
-					c.cl_dynamic <- Some t;
+					c.cl_dynamic <- Some (match t with None -> t_dynamic | Some t -> t);
 					(fun () -> ())
 				| _ ->
 					typing_error "Should implement by using an interface" p

+ 1 - 1
src/typing/typer.ml

@@ -873,7 +873,7 @@ and type_object_decl ctx fl with_type p =
 						| _ -> ODKFailed
 					end
 				end
-			| TDynamic t when (follow t != t_dynamic) ->
+			| TDynamic (Some t) ->
 				dynamic_parameter := Some t;
 				ODKWithStructure {
 					a_status = ref Closed;