diff --git a/src/context/typecore.ml b/src/context/typecore.ml index 7ec1d34ccab..b8b4a900ab4 100644 --- a/src/context/typecore.ml +++ b/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 diff --git a/src/core/tPrinting.ml b/src/core/tPrinting.ml index a7126d4d281..b3113df49da 100644 --- a/src/core/tPrinting.ml +++ b/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" diff --git a/src/core/tType.ml b/src/core/tType.ml index f313959a78a..882cb8db4f0 100644 --- a/src/core/tType.ml +++ b/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 diff --git a/src/core/tUnification.ml b/src/core/tUnification.ml index 6335fd4a5d7..e13718282d4 100644 --- a/src/core/tUnification.ml +++ b/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 = diff --git a/src/typing/callUnification.ml b/src/typing/callUnification.ml index bfeb4376d5e..b1c62a972e4 100644 --- a/src/typing/callUnification.ml +++ b/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 diff --git a/src/typing/forLoop.ml b/src/typing/forLoop.ml index a14f796c81b..e7ca441f5d2 100644 --- a/src/typing/forLoop.ml +++ b/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 () diff --git a/src/typing/matcher.ml b/src/typing/matcher.ml index 2149921be3c..40b2b46cc97 100644 --- a/src/typing/matcher.ml +++ b/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