Browse Source

[macro] properly unify function expressions passed to macros

Simon Krajewski 4 years ago
parent
commit
9cd32278ae
1 changed files with 13 additions and 3 deletions
  1. 13 3
      src/typing/macroContext.ml

+ 13 - 3
src/typing/macroContext.ml

@@ -661,7 +661,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 			try unify_raise mctx t expr p; (n, o, t_dynamic), MAExpr
 			with Error (Unify _,_) -> match follow t with
 				| TFun _ ->
-					(n,o,t_dynamic), MAFunction
+					(n,o,t), MAFunction
 				| _ ->
 					(n,o,t), MAOther
 			) margs in
@@ -673,6 +673,11 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 		let constants = List.map (fun e ->
 			let p = snd e in
 			let e =
+				let rec is_function e = match fst e with
+					| EFunction _ -> true
+					| EParenthesis e1 | ECast(e1,_) | EMeta(_,e1) -> is_function e1
+					| _ -> false
+				in
 				if Texpr.is_constant_value ctx.com.basic e then
 					(* temporarily disable format strings processing for macro call argument typing since we want to pass raw constants *)
 					let rec loop e =
@@ -681,6 +686,10 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 						| _ -> Ast.map_expr loop e
 					in
 					loop e
+				else if is_function e then
+					(* If we pass a function expression we don't want to type it as part of `unify_call_args` because that result just gets
+					   discarded. Use null here so it passes, then do the actual typing in the MAFunction part below. *)
+					(EConst (Ident "null"),p)
 				else
 					(* if it's not a constant, let's make something that is typed as haxe.macro.Expr - for nice error reporting *)
 					(ECheckType ((EConst (Ident "null"),p), (CTPath ctexpr,p)), p)
@@ -690,7 +699,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 			(EArray ((EArrayDecl [e],p),(EConst (Int (string_of_int (!index))),p)),p)
 		) el in
 		let elt = fst (CallUnification.unify_call_args mctx constants (List.map fst eargs) t_dynamic p false false false) in
-		List.map2 (fun (_,mct) e ->
+		List.map2 (fun ((n,_,t),mct) e ->
 			let e, et = (match e.eexpr with
 				(* get back our index and real expression *)
 				| TArray ({ eexpr = TArrayDecl [e] }, { eexpr = TConst (TInt index) }) -> List.nth el (Int32.to_int index), e
@@ -703,7 +712,8 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 			| MAExpr ->
 				Interp.encode_expr e
 			| MAFunction ->
-				let e = type_expr mctx e WithType.value in
+				let e = type_expr mctx e (WithType.with_argument t n) in
+				unify mctx e.etype t e.epos;
 				begin match Interp.eval_expr ictx e with
 				| Some v -> v
 				| None -> Interp.vnull