Selaa lähdekoodia

add MFromMacroInMacro constraint and check it when iterating/matching

Simon Krajewski 1 vuosi sitten
vanhempi
commit
3f2b9dc4a5

+ 11 - 0
src/context/typecore.ml

@@ -273,6 +273,17 @@ let spawn_monomorph' ctx p =
 let spawn_monomorph ctx p =
 	TMono (spawn_monomorph' ctx p)
 
+let extract_macro_in_macro_constraint m =
+	let rec loop l = match l with
+		| MFromMacroInMacro p :: _ ->
+			Some p
+		| _ :: l ->
+			loop l
+		| [] ->
+			None
+	in
+	loop m.tm_down_constraints
+
 let make_static_this c p =
 	let ta = mk_anon ~fields:c.cl_statics (ref (ClassStatics c)) in
 	mk (TTypeExpr (TClassDecl c)) ta p

+ 1 - 0
src/core/tPrinting.ml

@@ -127,6 +127,7 @@ and s_constraint = function
 	| MType(t,_) -> Printf.sprintf "MType %s" (s_type_kind t)
 	| MOpenStructure -> "MOpenStructure"
 	| MEmptyStructure -> "MEmptyStructure"
+	| MFromMacroInMacro _ -> "MFromMacroInMacro"
 
 let s_access is_read = function
 	| AccNormal -> "default"

+ 1 - 0
src/core/tType.ml

@@ -74,6 +74,7 @@ and tmono_constraint =
 	| MType of t * string option
 	| MOpenStructure
 	| MEmptyStructure
+	| MFromMacroInMacro of pos
 
 and tmono_constraint_kind =
 	| CUnknown

+ 2 - 0
src/core/tUnification.ml

@@ -128,6 +128,8 @@ module Monomorph = struct
 			| MOpenStructure
 			| MEmptyStructure ->
 				is_open := true
+			| MFromMacroInMacro _ ->
+				()
 		in
 		List.iter check m.tm_down_constraints;
 		let kind =

+ 17 - 2
src/typing/callUnification.ml

@@ -455,8 +455,23 @@ object(self)
 		let ethis_f = ref (fun () -> ()) in
 		let macro_in_macro () =
 			(fun () ->
-				let e = (EThrow((EConst(String("macro-in-macro",SDoubleQuotes))),p),p) in
-				type_expr ~mode ctx e with_type
+				let e_msg = Texpr.type_constant ctx.com.basic (String("macro-in-macro",SDoubleQuotes)) p in
+				let type_as t = mk (TThrow e_msg) t p in
+				match with_type with
+				| WithType.NoValue ->
+					type_as t_dynamic
+				| WithType.Value _ ->
+					let m = spawn_monomorph' ctx p in
+					Monomorph.add_down_constraint m (MFromMacroInMacro p);
+					type_as (TMono m)
+				| WithType(t,_) ->
+					begin match follow t with
+						| TMono m ->
+							Monomorph.add_down_constraint m (MFromMacroInMacro p);
+						| _ ->
+							()
+					end;
+					type_as t
 			)
 		in
 		let f = (match ethis.eexpr with

+ 21 - 3
src/typing/forLoop.ml

@@ -174,6 +174,18 @@ module IterationKind = struct
 			display_error ctx.com "You can't iterate on a Dynamic value, please specify Iterator or Iterable" e.epos;
 			IteratorDynamic,e,t_dynamic
 		in
+		let mono_iterator m e =
+			begin match extract_macro_in_macro_constraint m with
+			| Some p ->
+				let sub = if p <> e.epos then [Error.make_error (Custom "Call was here") p] else [] in
+				display_error_ext ctx.com (Error.make_error
+					~sub
+					(Custom "Cannot iterate on expression from macro-in-macro call") e.epos);
+			| None ->
+				display_error ctx.com "Cannot iterate on unknown value" e.epos;
+			end;
+			IteratorDynamic,e,t_dynamic
+		in
 		let check_iterator () =
 			let array_access_result = ref None in
 			let last_resort () =
@@ -185,8 +197,12 @@ module IterationKind = struct
 			| Some result -> result
 			| None ->
 				match Abstract.follow_with_abstracts e1.etype with
-					| (TMono _ | TDynamic _) -> dynamic_iterator e1;
-					| _ -> (IteratorIterator,e1,pt)
+					| TMono m ->
+						mono_iterator m e
+					| TDynamic _ ->
+						dynamic_iterator e1;
+					| _ ->
+						(IteratorIterator,e1,pt)
 		in
 		let try_forward_array_iterator () =
 			match follow e.etype with
@@ -251,7 +267,9 @@ module IterationKind = struct
 			with Not_found -> check_iterator ())
 		| _,TInst ({ cl_kind = KGenericInstance ({ cl_path = ["haxe";"ds"],"GenericStack" },[pt]) } as c,[]) ->
 			IteratorGenericStack c,e,pt
-		| _,(TMono _ | TDynamic _) ->
+		| _,TMono m ->
+			mono_iterator m e;
+		| _,TDynamic _ ->
 			dynamic_iterator e
 		| _ ->
 			check_iterator ()

+ 22 - 2
src/typing/matcher.ml

@@ -27,15 +27,35 @@ module Match = struct
 
 	let match_expr ctx e cases def with_type postfix_match p =
 		let match_debug = Meta.has (Meta.Custom ":matchDebug") ctx.curfield.cf_meta in
+		let check_mono e =
+			match follow e.etype with
+			| TMono m ->
+				begin match extract_macro_in_macro_constraint m with
+				| Some p ->
+					let sub = if p <> e.epos then [Error.make_error (Custom "Call was here") p] else [] in
+					Error.raise_typing_error_ext (Error.make_error
+						~sub
+						(Custom "Cannot match on expression from macro-in-macro call") e.epos);
+				| None ->
+					()
+				end
+			| _ ->
+				()
+		in
+		let type_expr e =
+			let e = type_expr ctx e WithType.value in
+			check_mono e;
+			e
+		in
 		let rec loop e = match fst e with
 			| EArrayDecl el when (match el with [(EFor _ | EWhile _),_] -> false | _ -> true) ->
-				let el = List.map (fun e -> type_expr ctx e WithType.value) el in
+				let el = List.map type_expr el in
 				let t = ExprToPattern.tuple_type (List.map (fun e -> e.etype) el) in
 				t,el
 			| EParenthesis e1 ->
 				loop e1
 			| _ ->
-				let e = type_expr ctx e WithType.value in
+				let e = type_expr e in
 				e.etype,[e]
 		in
 		let t,subjects = loop e in