浏览代码

Merge branch 'development' into deprecate_meta_overloads

Simon Krajewski 9 月之前
父节点
当前提交
95582b4e7e
共有 86 个文件被更改,包括 515 次插入271 次删除
  1. 0 2
      .github/workflows/main.yml
  2. 0 2
      extra/github-actions/build-mac.yml
  3. 7 5
      src/compiler/compiler.ml
  4. 1 1
      src/compiler/displayProcessing.ml
  5. 8 4
      src/context/abstractCast.ml
  6. 2 1
      src/context/common.ml
  7. 0 11
      src/context/resolution.ml
  8. 0 1
      src/context/sourcemaps.ml
  9. 0 6
      src/context/typecore.ml
  10. 8 2
      src/core/error.ml
  11. 6 3
      src/core/tFunctions.ml
  12. 13 8
      src/core/tPrinting.ml
  13. 6 1
      src/core/tType.ml
  14. 21 14
      src/core/tUnification.ml
  15. 38 21
      src/filters/exceptions.ml
  16. 6 6
      src/filters/filters.ml
  17. 1 4
      src/generators/cpp/cppAst.ml
  18. 1 3
      src/generators/cpp/cppAstTools.ml
  19. 1 6
      src/generators/cpp/cppContext.ml
  20. 1 5
      src/generators/cpp/cppExprUtils.ml
  21. 0 2
      src/generators/cpp/cppRetyper.ml
  22. 1 6
      src/generators/cpp/cppSourceWriter.ml
  23. 1 5
      src/generators/cpp/cppTypeUtils.ml
  24. 0 2
      src/generators/cpp/gen/cppCppia.ml
  25. 1 2
      src/generators/cpp/gen/cppGen.ml
  26. 1 2
      src/generators/cpp/gen/cppGenClassHeader.ml
  27. 1 2
      src/generators/cpp/gen/cppGenClassImplementation.ml
  28. 0 6
      src/generators/cpp/gen/cppGenEnum.ml
  29. 0 6
      src/generators/cpp/gen/cppReferences.ml
  30. 1 3
      src/generators/gencpp.ml
  31. 1 1
      src/generators/genhl.ml
  32. 0 1
      src/generators/genswf.ml
  33. 0 4
      src/macro/eval/evalContext.ml
  34. 4 4
      src/macro/eval/evalDebugSocket.ml
  35. 1 6
      src/macro/eval/evalEncode.ml
  36. 1 1
      src/macro/eval/evalMain.ml
  37. 4 4
      src/macro/eval/evalMisc.ml
  38. 1 1
      src/macro/eval/evalPrinting.ml
  39. 1 1
      src/macro/eval/evalStdLib.ml
  40. 4 4
      src/macro/eval/evalValue.ml
  41. 20 20
      src/macro/macroApi.ml
  42. 1 1
      src/optimization/inline.ml
  43. 6 1
      src/syntax/reification.ml
  44. 12 0
      src/typing/callUnification.ml
  45. 1 1
      src/typing/fields.ml
  46. 15 8
      src/typing/finalization.ml
  47. 4 3
      src/typing/forLoop.ml
  48. 13 20
      src/typing/macroContext.ml
  49. 1 1
      src/typing/nullSafety.ml
  50. 2 2
      src/typing/operators.ml
  51. 3 9
      src/typing/typeload.ml
  52. 1 3
      src/typing/typer.ml
  53. 8 1
      src/typing/typerEntry.ml
  54. 10 0
      std/haxe/macro/Expr.hx
  55. 2 2
      std/hl/types/ArrayBytes.hx
  56. 2 2
      std/hl/types/ArrayObj.hx
  57. 10 0
      tests/misc/projects/Issue11431/Main.hx
  58. 2 0
      tests/misc/projects/Issue11431/compile-fail.hxml
  59. 1 0
      tests/misc/projects/Issue11431/compile-fail.hxml.stderr
  60. 1 1
      tests/misc/projects/Issue11624/compile-bar-fail.hxml.stderr
  61. 1 1
      tests/misc/projects/Issue11624/compile-foo-fail.hxml.stderr
  62. 2 0
      tests/misc/projects/Issue11632/compile-test.hxml.stdout
  63. 31 0
      tests/misc/projects/Issue11753/Main.hx
  64. 28 0
      tests/misc/projects/Issue11753/Main2.hx
  65. 4 0
      tests/misc/projects/Issue11753/compile-fail.hxml
  66. 32 0
      tests/misc/projects/Issue11753/compile-fail.hxml.stderr
  67. 4 0
      tests/misc/projects/Issue11753/compile.hxml
  68. 29 0
      tests/misc/projects/Issue11753/compile.hxml.stderr
  69. 3 0
      tests/misc/projects/Issue5456/Main.hx
  70. 16 0
      tests/misc/projects/Issue5456/Test.hx
  71. 20 0
      tests/misc/projects/Issue5456/TestBuilder.hx
  72. 2 0
      tests/misc/projects/Issue5456/compile.hxml
  73. 1 0
      tests/misc/projects/Issue5456/compile.hxml.stdout
  74. 7 0
      tests/misc/projects/Issue5456/test/C.hx
  75. 3 0
      tests/misc/projects/Issue6321/A.hx
  76. 4 0
      tests/misc/projects/Issue6321/B.hx
  77. 14 0
      tests/misc/projects/Issue6321/Macro.hx
  78. 12 0
      tests/misc/projects/Issue6321/MacroFail.hx
  79. 1 0
      tests/misc/projects/Issue6321/compile-fail.hxml
  80. 2 0
      tests/misc/projects/Issue6321/compile-fail.hxml.stderr
  81. 1 0
      tests/misc/projects/Issue6321/compile.hxml
  82. 2 0
      tests/misc/projects/Issue6321/compile.hxml.stdout
  83. 7 0
      tests/misc/projects/Issue6321/test/C.hx
  84. 12 0
      tests/unit/src/unit/issues/Issue11810.hx
  85. 0 11
      tests/unit/src/unit/issues/Issue3024.hx
  86. 19 15
      tests/unit/src/unit/issues/misc/Issue3183Macro.hx

+ 0 - 2
.github/workflows/main.yml

@@ -501,8 +501,6 @@ jobs:
         run: |
           set -ex
           brew update
-          brew uninstall --force pkg-config
-          brew install pkgconf --overwrite
           brew bundle --file=tests/Brewfile --no-upgrade
           cpanm IPC::System::Simple
           cpanm String::ShellQuote

+ 0 - 2
extra/github-actions/build-mac.yml

@@ -7,8 +7,6 @@
   run: |
     set -ex
     brew update
-    brew uninstall --force pkg-config
-    brew install pkgconf --overwrite
     brew bundle --file=tests/Brewfile --no-upgrade
     cpanm IPC::System::Simple
     cpanm String::ShellQuote

+ 7 - 5
src/compiler/compiler.ml

@@ -329,18 +329,19 @@ let do_type ctx mctx actx display_file_dot_path =
 let finalize_typing ctx tctx =
 	let t = Timer.timer ["finalize"] in
 	let com = ctx.com in
+	let main_module = Finalization.maybe_load_main tctx in
 	enter_stage com CFilteringStart;
 	ServerMessage.compiler_stage com;
-	let main, types, modules = run_or_diagnose ctx (fun () -> Finalization.generate tctx) in
+	let main, types, modules = run_or_diagnose ctx (fun () -> Finalization.generate tctx main_module) in
 	com.main.main_expr <- main;
 	com.types <- types;
 	com.modules <- modules;
 	t()
 
-let filter ctx tctx before_destruction =
+let filter ctx tctx ectx before_destruction =
 	let t = Timer.timer ["filters"] in
 	DeprecationCheck.run ctx.com;
-	run_or_diagnose ctx (fun () -> Filters.run tctx ctx.com.main.main_expr before_destruction);
+	run_or_diagnose ctx (fun () -> Filters.run tctx ectx ctx.com.main.main_expr before_destruction);
 	t()
 
 let compile ctx actx callbacks =
@@ -382,6 +383,7 @@ let compile ctx actx callbacks =
 		(* Actual compilation starts here *)
 		let (tctx,display_file_dot_path) = do_type ctx mctx actx display_file_dot_path in
 		DisplayProcessing.handle_display_after_typing ctx tctx display_file_dot_path;
+		let ectx = Exceptions.create_exception_context tctx in
 		finalize_typing ctx tctx;
 		let is_compilation = is_compilation com in
 		com.callbacks#add_after_save (fun () ->
@@ -393,10 +395,10 @@ let compile ctx actx callbacks =
 					()
 		);
 		if is_diagnostics com then
-			filter ctx tctx (fun () -> DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path)
+			filter ctx tctx ectx (fun () -> DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path)
 		else begin
 			DisplayProcessing.handle_display_after_finalization ctx tctx display_file_dot_path;
-			filter ctx tctx (fun () -> ());
+			filter ctx tctx ectx (fun () -> ());
 		end;
 		if ctx.has_error then raise Abort;
 		if is_compilation then Generate.check_auxiliary_output com actx;

+ 1 - 1
src/compiler/displayProcessing.ml

@@ -348,7 +348,7 @@ let handle_display_after_finalization ctx tctx display_file_dot_path =
 		| None -> ()
 		| Some mctx ->
 			(* We don't need a full macro flush here because we're not going to run any macros. *)
-			let _, types, modules = Finalization.generate mctx in
+			let _, types, modules = Finalization.generate mctx (Finalization.maybe_load_main mctx) in
 			mctx.Typecore.com.types <- types;
 			mctx.Typecore.com.Common.modules <- modules
 	end;

+ 8 - 4
src/context/abstractCast.ml

@@ -23,7 +23,7 @@ let rec make_static_call ctx c cf a pl args t p =
 				e
 			| _ -> die "" __LOC__
 	end else
-		Typecore.make_static_call ctx c cf (apply_params a.a_params pl) args t p
+		CallUnification.make_static_call_better ctx c cf pl args t p
 
 and do_check_cast ctx uctx tleft eright p =
 	let recurse cf f =
@@ -199,7 +199,7 @@ let find_array_write_access ctx a tl e1 e2 p =
 		let s_type = s_type (print_context()) in
 		raise_typing_error (Printf.sprintf "No @:arrayAccess function for %s accepts arguments of %s and %s" (s_type (TAbstract(a,tl))) (s_type e1.etype) (s_type e2.etype)) p
 
-let find_multitype_specialization com a pl p =
+let find_multitype_specialization' com a pl p =
 	let uctx = default_unification_context in
 	let m = mk_mono() in
 	let tl,definitive_types = Abstract.find_multitype_params a pl in
@@ -241,7 +241,11 @@ let find_multitype_specialization com a pl p =
 			else
 				raise_typing_error ("Abstract " ^ (s_type_path a.a_path) ^ " has no @:to function that accepts " ^ st) p;
 	in
-	cf, follow m
+	cf,follow m,tl
+
+let find_multitype_specialization com a pl p =
+	let cf,m,_ = find_multitype_specialization' com a pl p in
+	(cf,m)
 
 let handle_abstract_casts ctx e =
 	let rec loop e = match e.eexpr with
@@ -254,7 +258,7 @@ let handle_abstract_casts ctx e =
 				| _ -> raise_typing_error ("Cannot construct " ^ (s_type (print_context()) (TAbstract(a,pl)))) e.epos
 			end else begin
 				(* a TNew of an abstract implementation is only generated if it is a multi type abstract *)
-				let cf,m = find_multitype_specialization ctx.com a pl e.epos in
+				let cf,m,pl = find_multitype_specialization' ctx.com a pl e.epos in
 				let e = make_static_call ctx c cf a pl ((mk (TConst TNull) (TAbstract(a,pl)) e.epos) :: el) m e.epos in
 				{e with etype = m}
 			end

+ 2 - 1
src/context/common.ml

@@ -16,7 +16,6 @@
 	along with this program; if not, write to the Free Software
 	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *)
-open Extlib_leftovers
 open Ast
 open Type
 open Globals
@@ -860,6 +859,7 @@ let create compilation_step cs version args display_mode =
 			tstring = mk_mono();
 			tnull = (fun _ -> die "Could use locate abstract Null<T> (was it redefined?)" __LOC__);
 			tarray = (fun _ -> die "Could not locate class Array<T> (was it redefined?)" __LOC__);
+			titerator = (fun _ -> die "Could not locate typedef Iterator<T> (was it redefined?)" __LOC__);
 		};
 		std = null_class;
 		file_keys = new file_keys;
@@ -899,6 +899,7 @@ let clone com is_macro_context =
 	let t = com.basic in
 	{ com with
 		cache = None;
+		stage = CCreated;
 		basic = { t with
 			tvoid = mk_mono();
 			tany = mk_mono();

+ 0 - 11
src/context/resolution.ml

@@ -203,17 +203,6 @@ class resolution_list (id : string list) = object(self)
 		self#cache_type_imports;
 		StringMap.find alias type_import_cache
 
-	method find_type_import_weirdly pack name =
-		let rec find l = match l with
-			| [] ->
-				raise Not_found
-			| {r_kind = RTypeImport(alias,mt); r_pos = p} :: l ->
-				if  t_path mt = (pack,name) then (mt,p) else find l
-			| _ :: l ->
-				find l
-		in
-		find l
-
 	method extract_type_imports =
 		ExtList.List.filter_map (fun res -> match res.r_kind with
 			| RTypeImport(_,mt) ->

+ 0 - 1
src/context/sourcemaps.ml

@@ -1,6 +1,5 @@
 open Extlib_leftovers
 open Globals
-open Gctx
 
 (**
 	Characters used for base64 VLQ encoding

+ 0 - 6
src/context/typecore.ml

@@ -384,12 +384,6 @@ let make_static_field_access c cf t p =
 	let ethis = Texpr.Builder.make_static_this c p in
 	mk (TField (ethis,(FStatic (c,cf)))) t p
 
-let make_static_call ctx c cf map args t p =
-	let monos = List.map (fun _ -> spawn_monomorph ctx.e p) cf.cf_params in
-	let map t = map (apply_params cf.cf_params monos t) in
-	let ef = make_static_field_access c cf (map cf.cf_type) p in
-	make_call ctx ef args (map t) p
-
 let raise_with_type_error ?(depth = 0) msg p =
 	raise (WithTypeError (make_error ~depth (Custom msg) p))
 

+ 8 - 2
src/core/error.ml

@@ -184,8 +184,14 @@ module BetterErrors = struct
 		match t with
 		| TMono r ->
 			(match r.tm_type with
-			| None -> Printf.sprintf "Unknown<%d>" (try List.assq t (!ctx) with Not_found -> let n = List.length !ctx in ctx := (t,n) :: !ctx; n)
-			| Some t -> s_type ctx t)
+			| None ->
+				let name = Printf.sprintf "Unknown<%d>" (try List.assq t (!ctx) with Not_found -> let n = List.length !ctx in ctx := (t,n) :: !ctx; n) in
+				List.fold_left (fun s modi -> match modi with
+					| MNullable _ -> Printf.sprintf "Null<%s>" s
+					| MOpenStructure -> s
+				) name r.tm_modifiers
+			| Some t ->
+				s_type ctx t)
 		| TEnum (e,tl) ->
 			s_type_path e.e_path ^ s_type_params ctx tl
 		| TInst (c,tl) ->

+ 6 - 3
src/core/tFunctions.ml

@@ -646,9 +646,12 @@ let rec ambiguate_funs t =
 	| TFun _ -> TFun ([], t_dynamic)
 	| _ -> map ambiguate_funs t
 
+let is_nullable_mono m =
+	List.exists (function MNullable _ -> true | _ -> false) m.tm_modifiers
+
 let rec is_nullable ?(no_lazy=false) = function
 	| TMono r ->
-		(match r.tm_type with None -> false | Some t -> is_nullable ~no_lazy t)
+		(match r.tm_type with None -> is_nullable_mono r | Some t -> is_nullable ~no_lazy t)
 	| TAbstract ({ a_path = ([],"Null") },[_]) ->
 		true
 	| TLazy f ->
@@ -679,7 +682,7 @@ let rec is_nullable ?(no_lazy=false) = function
 
 let rec is_null ?(no_lazy=false) = function
 	| TMono r ->
-		(match r.tm_type with None -> false | Some t -> is_null ~no_lazy t)
+		(match r.tm_type with None -> is_nullable_mono r | Some t -> is_null ~no_lazy t)
 	| TAbstract ({ a_path = ([],"Null") },[t]) ->
 		not (is_nullable ~no_lazy (follow t))
 	| TLazy f ->
@@ -696,7 +699,7 @@ let rec is_null ?(no_lazy=false) = function
 (* Determines if we have a Null<T>. Unlike is_null, this returns true even if the wrapped type is nullable itself. *)
 let rec is_explicit_null = function
 	| TMono r ->
-		(match r.tm_type with None -> false | Some t -> is_explicit_null t)
+		(match r.tm_type with None -> is_nullable_mono r | Some t -> is_explicit_null t)
 	| TAbstract ({ a_path = ([],"Null") },[t]) ->
 		true
 	| TLazy f ->

+ 13 - 8
src/core/tPrinting.ml

@@ -35,12 +35,21 @@ let rec s_type ctx t =
 	| TMono r ->
 		(match r.tm_type with
 		| None ->
-			begin try
-				let id = List.assq t (!ctx) in
-				if show_mono_ids then
+			let print_name id extra =
+				let s = if show_mono_ids then
 					Printf.sprintf "Unknown<%d>" id
 				else
 					"Unknown"
+				in
+				let s = s ^ extra in
+				List.fold_left (fun s modi -> match modi with
+					| MNullable _ -> Printf.sprintf "Null<%s>" s
+					| MOpenStructure -> s
+				) s r.tm_modifiers
+			in
+			begin try
+				let id = List.assq t (!ctx) in
+				print_name id ""
 			with Not_found ->
 				let id = List.length !ctx in
 				ctx := (t,id) :: !ctx;
@@ -54,10 +63,7 @@ let rec s_type ctx t =
 					let s = loop (!monomorph_classify_constraints_ref r) in
 					if s = "" then s else " : " ^ s
 				in
-				if show_mono_ids then
-					Printf.sprintf "Unknown<%d>%s" id s_const
-				else
-					Printf.sprintf "Unknown%s" s_const
+				print_name id s_const
 			end
 		| Some t -> s_type ctx t)
 	| TEnum (e,tl) ->
@@ -125,7 +131,6 @@ and s_constraint = function
 	| MMono(m,_) -> Printf.sprintf "MMono %s" (s_type_kind (TMono m))
 	| MField cf -> Printf.sprintf "MField %s" cf.cf_name
 	| MType(t,_) -> Printf.sprintf "MType %s" (s_type_kind t)
-	| MOpenStructure -> "MOpenStructure"
 	| MEmptyStructure -> "MEmptyStructure"
 
 let s_type_param s_type ttp =

+ 6 - 1
src/core/tType.ml

@@ -83,13 +83,13 @@ and tmono = {
 	*)
 	mutable tm_down_constraints : tmono_constraint list;
 	mutable tm_up_constraints : (t * string option) list;
+	mutable tm_modifiers : tmono_modifier list;
 }
 
 and tmono_constraint =
 	| MMono of tmono * string option
 	| MField of tclass_field
 	| MType of t * string option
-	| MOpenStructure
 	| MEmptyStructure
 
 and tmono_constraint_kind =
@@ -98,6 +98,10 @@ and tmono_constraint_kind =
 	| CMixed of tmono_constraint_kind list
 	| CTypes of (t * string option) list
 
+and tmono_modifier =
+	| MNullable of (t -> t)
+	| MOpenStructure
+
 and tlazy =
 	| LAvailable of t
 	| LProcessing of t
@@ -473,6 +477,7 @@ type basic_types = {
 	mutable tnull : t -> t;
 	mutable tstring : t;
 	mutable tarray : t -> t;
+	mutable titerator : t -> t
 }
 
 type class_field_scope =

+ 21 - 14
src/core/tUnification.ml

@@ -93,9 +93,13 @@ module Monomorph = struct
 	let create () = {
 		tm_type = None;
 		tm_down_constraints = [];
-		tm_up_constraints = []
+		tm_up_constraints = [];
+		tm_modifiers = [];
 	}
 
+	let add_modifier m modi =
+		m.tm_modifiers <- modi :: m.tm_modifiers
+
 	(* constraining *)
 
 	let add_up_constraint m ((t,name) as constr) =
@@ -127,21 +131,18 @@ module Monomorph = struct
 
 	(* Note: This function is called by printing and others and should thus not modify state. *)
 
-	let rec classify_down_constraints' m =
+	let rec classify_down_constraints m =
 		let types = DynArray.create () in
 		let fields = ref PMap.empty in
 		let is_open = ref false in
-		let monos = ref [] in
 		let rec check constr = match constr with
 			| MMono(m2,name) ->
 				begin match m2.tm_type with
 				| None ->
-					let more_monos,kind = classify_down_constraints' m2 in
-					monos := !monos @ more_monos;
+					let kind = classify_down_constraints m2 in
 					begin match kind with
 					| CUnknown ->
-						(* Collect unconstrained monomorphs because we have to bind them. *)
-						monos := m2 :: !monos;
+						()
 					| _ ->
 						(* Recursively inherit constraints. *)
 						List.iter check m2.tm_down_constraints
@@ -153,11 +154,16 @@ module Monomorph = struct
 				fields := PMap.add cf.cf_name cf !fields;
 			| MType(t2,name) ->
 				DynArray.add types (t2,name)
-			| MOpenStructure
 			| MEmptyStructure ->
 				is_open := true
 		in
 		List.iter check m.tm_down_constraints;
+		List.iter (function
+			| MNullable _ ->
+				()
+			| MOpenStructure ->
+				is_open := true
+		) m.tm_modifiers;
 		let kind =
 			let k1 =
 				if DynArray.length types > 0 then
@@ -173,9 +179,7 @@ module Monomorph = struct
 			else
 				k1
 		in
-		!monos,kind
-
-	let classify_down_constraints m = snd (classify_down_constraints' m)
+		kind
 
 	let rec check_down_constraints constr t =
 		match constr with
@@ -225,13 +229,17 @@ module Monomorph = struct
 
 	let do_bind m t =
 		(* assert(m.tm_type = None); *) (* TODO: should be here, but matcher.ml does some weird bind handling at the moment. *)
+		let t = List.fold_left (fun t modi -> match modi with
+			| MNullable f -> f t
+			| MOpenStructure -> t
+		) t m.tm_modifiers in
 		m.tm_type <- Some t;
 		m.tm_down_constraints <- [];
 		m.tm_up_constraints <- []
 
 	let rec bind m t =
 		begin match t with
-		| TAnon _ when List.mem MOpenStructure m.tm_down_constraints ->
+		| TAnon _ when List.mem MOpenStructure m.tm_modifiers ->
 			(* If we assign an open structure monomorph to another structure, the semantics want us to merge the
 			   fields. This is kinda weird, but that's how it has always worked. *)
 			constrain_to_type m None t;
@@ -272,8 +280,7 @@ module Monomorph = struct
 				with Type_exception t ->
 					Some t
 			in
-			(* TODO: we never do anything with monos, I think *)
-			let monos,constraints = classify_down_constraints' m in
+			let constraints = classify_down_constraints m in
 			match constraints with
 			| CUnknown ->
 				()

+ 38 - 21
src/filters/exceptions.ml

@@ -40,7 +40,7 @@ let haxe_exception_static_call ctx method_name args p =
 		| _ -> raise_typing_error ("haxe.Exception." ^ method_name ^ " is not a function and cannot be called") p
 	in
 	add_dependency ctx.typer.c.curclass.cl_module ctx.haxe_exception_class.cl_module MDepFromTyping;
-	make_static_call ctx.typer ctx.haxe_exception_class method_field (fun t -> t) args return_type p
+	CallUnification.make_static_call_better ctx.typer ctx.haxe_exception_class method_field [] args return_type p
 
 (**
 	Generate `haxe_exception.method_name(args)`
@@ -74,7 +74,7 @@ let std_is ctx e t p =
 		| _ -> raise_typing_error ("Std.isOfType is not a function and cannot be called") p
 	in
 	let type_expr = TyperBase.type_module_type ctx.typer (module_type_of_type t) p in
-	make_static_call ctx.typer std_cls isOfType_field (fun t -> t) [e; type_expr] return_type p
+	CallUnification.make_static_call_better ctx.typer std_cls isOfType_field [] [e; type_expr] return_type p
 
 (**
 	Check if type path of `t` exists in `lst`
@@ -492,12 +492,7 @@ let catch_native ctx catches t p =
 	in
 	transform [] None catches
 
-(**
-	Transform `throw` and `try..catch` expressions.
-	`rename_locals` is required to deal with the names of temp vars.
-*)
-let filter tctx =
-	let stub e = e in
+let create_exception_context tctx =
 	match tctx.com.platform with (* TODO: implement for all targets *)
 	| Php | Js | Jvm | Python | Lua | Eval | Neko | Flash | Hl | Cpp ->
 		let config = tctx.com.config.pf_exceptions in
@@ -549,6 +544,18 @@ let filter tctx =
 			value_exception_type = value_exception_type;
 			value_exception_class = value_exception_class;
 		} in
+		Some ctx
+	| Cross | CustomTarget _ ->
+		None
+
+(**
+	Transform `throw` and `try..catch` expressions.
+	`rename_locals` is required to deal with the names of temp vars.
+*)
+let filter ectx =
+	let stub e = e in
+	match ectx with
+	| Some ctx ->
 		let rec run e =
 			match e.eexpr with
 			| TThrow e1 ->
@@ -566,22 +573,18 @@ let filter tctx =
 			if contains_throw_or_try e then run e
 			else stub e
 		)
-	| Cross | CustomTarget _ -> stub
+	| None ->
+		stub
 
 (**
 	Inserts `haxe.NativeStackTrace.saveStack(e)` in non-haxe.Exception catches.
 *)
-let insert_save_stacks tctx =
+let insert_save_stacks ectx =
+	let tctx = ectx.typer in
 	if not (has_feature tctx.com "haxe.NativeStackTrace.exceptionStack") then
 		(fun e -> e)
 	else
-		let native_stack_trace_cls =
-			let tp = mk_type_path (["haxe"],"NativeStackTrace") in
-			match Typeload.load_type_def tctx null_pos tp with
-			| TClassDecl cls -> cls
-			| TAbstractDecl { a_impl = Some cls } -> cls
-			| _ -> raise_typing_error "haxe.NativeStackTrace is expected to be a class or an abstract" null_pos
-		in
+		let native_stack_trace_cls = ectx.haxe_native_stack_trace in
 		let rec contains_insertion_points e =
 			match e.eexpr with
 			| TTry (e, catches) ->
@@ -606,7 +609,7 @@ let insert_save_stacks tctx =
 				let catch_local = mk (TLocal catch_var) catch_var.v_type catch_var.v_pos in
 				begin
 					add_dependency tctx.c.curclass.cl_module native_stack_trace_cls.cl_module MDepFromTyping;
-					make_static_call tctx native_stack_trace_cls method_field (fun t -> t) [catch_local] return_type catch_var.v_pos
+					CallUnification.make_static_call_better tctx native_stack_trace_cls method_field [] [catch_local] return_type catch_var.v_pos
 				end
 			else
 				mk (TBlock[]) tctx.t.tvoid catch_var.v_pos
@@ -639,12 +642,19 @@ let insert_save_stacks tctx =
 			else e
 		)
 
+let insert_save_stacks tctx ectx =
+	match ectx with
+	| Some ctx ->
+		insert_save_stacks {ctx with typer = tctx}
+	| None ->
+		(fun e -> e)
+
 (**
 	Adds `this.__shiftStack()` calls to constructors of classes which extend `haxe.Exception`
 *)
-let patch_constructors tctx =
-	let tp = make_ptp (mk_type_path haxe_exception_type_path) null_pos in
-	match Typeload.load_instance tctx tp ParamSpawnMonos LoadNormal with
+let patch_constructors ectx =
+	let tctx = ectx.typer in
+	match ectx.haxe_exception_type with
 	(* Add only if `__shiftStack` method exists *)
 	| TInst(cls,_) when PMap.mem "__shiftStack" cls.cl_fields ->
 		(fun mt ->
@@ -694,3 +704,10 @@ let patch_constructors tctx =
 			| _ -> ()
 		)
 	| _ -> (fun _ -> ())
+
+let patch_constructors tctx ectx =
+	match ectx with
+	| Some ctx ->
+		patch_constructors {ctx with typer = tctx}
+	| None ->
+		(fun _ -> ())

+ 6 - 6
src/filters/filters.ml

@@ -459,7 +459,7 @@ end
 
 open FilterContext
 
-let destruction tctx detail_times main locals =
+let destruction tctx ectx detail_times main locals =
 	let com = tctx.com in
 	with_timer detail_times "type 2" None (fun () ->
 		(* PASS 2: type filters pre-DCE *)
@@ -491,11 +491,11 @@ let destruction tctx detail_times main locals =
 			tctx
 			detail_times
 			(* This has to run after DCE, or otherwise its condition always holds. *)
-			["insert_save_stacks",Exceptions.insert_save_stacks]
+			["insert_save_stacks",(fun tctx -> Exceptions.insert_save_stacks tctx ectx)]
 		)
 		com.types;
 	let type_filters = [
-		Exceptions.patch_constructors; (* TODO: I don't believe this should load_instance anything at this point... *)
+		(fun tctx -> Exceptions.patch_constructors tctx ectx); (* TODO: I don't believe this should load_instance anything at this point... *)
 		(fun _ -> check_private_path com);
 		(fun _ -> Naming.apply_native_paths);
 		(fun _ -> add_rtti com);
@@ -666,7 +666,7 @@ let might_need_cf_unoptimized c cf =
 	| _ ->
 		has_class_field_flag cf CfGeneric
 
-let run tctx main before_destruction =
+let run tctx ectx main before_destruction =
 	let com = tctx.com in
 	let detail_times = (try int_of_string (Common.defined_value_safe com ~default:"0" Define.FilterTimes) with _ -> 0) in
 	let new_types = List.filter (fun t ->
@@ -719,7 +719,7 @@ let run tctx main before_destruction =
 		"Tre",if defined com Define.AnalyzerOptimize then Tre.run else (fun _ e -> e);
 		"reduce_expression",Optimizer.reduce_expression;
 		"inline_constructors",InlineConstructors.inline_constructors;
-		"Exceptions_filter",Exceptions.filter;
+		"Exceptions_filter",(fun _ -> Exceptions.filter ectx);
 		"captured_vars",(fun _ -> CapturedVars.captured_vars com);
 	] in
 	List.iter (run_expression_filters tctx detail_times filters) new_types;
@@ -765,4 +765,4 @@ let run tctx main before_destruction =
 		com.callbacks#run com.error_ext com.callbacks#get_after_save;
 	);
 	before_destruction();
-	destruction tctx detail_times main locals
+	destruction tctx ectx detail_times main locals

+ 1 - 4
src/generators/cpp/cppAst.ml

@@ -1,7 +1,4 @@
-open Extlib_leftovers
-open Ast
 open Type
-open Error
 open Globals
 
 type tcpp =
@@ -154,4 +151,4 @@ and tcpp_expr_expr =
   | CppCastObjC of tcppexpr * tclass
   | CppCastObjCBlock of tcppexpr * tcpp list * tcpp
   | CppCastProtocol of tcppexpr * tclass
-  | CppCastNative of tcppexpr
+  | CppCastNative of tcppexpr

+ 1 - 3
src/generators/cpp/cppAstTools.ml

@@ -1,7 +1,5 @@
-open Extlib_leftovers
 open Ast
 open Type
-open Error
 open Globals
 open CppAst
 open CppTypeUtils
@@ -726,4 +724,4 @@ let enum_getter_type t =
   | TCppScalar "int"  -> "Int"
   | TCppScalar "bool"  -> "Bool"
   | TCppScalar x  -> x
-  | _  -> "Object"
+  | _  -> "Object"

+ 1 - 6
src/generators/cpp/cppContext.ml

@@ -1,9 +1,4 @@
-open Extlib_leftovers
-open Ast
 open Gctx
-open Type
-open Error
-open Globals
 open CppAstTools
 
 (* CPP code generation context *)
@@ -98,4 +93,4 @@ let is_gc_element ctx member_type =
 
 let strip_file ctx file = match Gctx.defined ctx Define.AbsolutePath with
   | true -> Path.get_full_path file
-  | false -> ctx.class_paths#relative_path file
+  | false -> ctx.class_paths#relative_path file

+ 1 - 5
src/generators/cpp/cppExprUtils.ml

@@ -1,8 +1,4 @@
-open Extlib_leftovers
-open Ast
 open Type
-open Error
-open Globals
 
 let rec remove_parens expression =
   match expression.eexpr with
@@ -20,4 +16,4 @@ let rec remove_parens_cast expression =
 let is_static_access obj =
   match (remove_parens obj).eexpr with
   | TTypeExpr _ -> true
-  | _ -> false
+  | _ -> false

+ 0 - 2
src/generators/cpp/cppRetyper.ml

@@ -1,9 +1,7 @@
-open Extlib_leftovers
 open Ast
 open Type
 open Error
 open Globals
-open CppExprUtils
 open CppTypeUtils
 open CppAst
 open CppAstTools

+ 1 - 6
src/generators/cpp/cppSourceWriter.ml

@@ -1,9 +1,4 @@
-open Extlib_leftovers
-open Ast
 open Gctx
-open Type
-open Error
-open Globals
 open CppStrings
 open CppAstTools
 open CppTypeUtils
@@ -185,4 +180,4 @@ let new_placed_cpp_file common_ctx class_path =
       ( base_dir ^ "/src/" ^ ( String.concat "-" (fst class_path) ) ^ "-" ^
       (snd class_path) ^ (source_file_extension common_ctx) )
   end else
-    new_cpp_file common_ctx common_ctx.file class_path
+    new_cpp_file common_ctx common_ctx.file class_path

+ 1 - 5
src/generators/cpp/cppTypeUtils.ml

@@ -1,11 +1,7 @@
 (* Various helper functions to run checks on haxe classes and various other ast types *)
 (* functions in here operate on standard haxe ast types, not gencpp ast types *)
 
-open Extlib_leftovers
-open Ast
 open Type
-open Error
-open Globals
 
 let follow = Abstract.follow_with_abstracts
 
@@ -354,4 +350,4 @@ let class_name class_def =
   let nativeGen       = Meta.has Meta.NativeGen class_def.cl_meta in
   class_path ^ if nativeGen then "" else "_obj"
 
-let class_pointer class_def = "::hx::ObjectPtr< " ^ class_name class_def ^ " >"
+let class_pointer class_def = "::hx::ObjectPtr< " ^ class_name class_def ^ " >"

+ 0 - 2
src/generators/cpp/gen/cppCppia.ml

@@ -1,4 +1,3 @@
-open Extlib_leftovers
 open Ast
 open Type
 open Error
@@ -7,7 +6,6 @@ open CppExprUtils
 open CppTypeUtils
 open CppAst
 open CppAstTools
-open CppSourceWriter
 open CppContext
 
 let cpp_type_of = CppRetyper.cpp_type_of

+ 1 - 2
src/generators/cpp/gen/cppGen.ml

@@ -4,7 +4,6 @@ open Type
 open Error
 open Globals
 open CppStrings
-open CppExprUtils
 open CppTypeUtils
 open CppAst
 open CppAstTools
@@ -2045,4 +2044,4 @@ let dynamic_functions class_def =
         when is_dynamic_haxe_method field ->
           keyword_remap field.cf_name :: result
       | _ -> result)
-    [] class_def.cl_ordered_fields
+    [] class_def.cl_ordered_fields

+ 1 - 2
src/generators/cpp/gen/cppGenClassHeader.ml

@@ -3,7 +3,6 @@ open Type
 open Error
 open Globals
 open CppStrings
-open CppExprUtils
 open CppTypeUtils
 open CppAst
 open CppAstTools
@@ -549,4 +548,4 @@ let generate baseCtx class_def =
 
   end_header_file output_h def_string;
 
-  h_file#close
+  h_file#close

+ 1 - 2
src/generators/cpp/gen/cppGenClassImplementation.ml

@@ -3,7 +3,6 @@ open Type
 open Error
 open Globals
 open CppStrings
-open CppExprUtils
 open CppTypeUtils
 open CppAst
 open CppAstTools
@@ -1389,4 +1388,4 @@ let generate baseCtx class_def =
      ^ "_delegate alloc] initWithImplementation:inImplementation.mPtr];\n");
     output_cpp "}\n\n");
 
-  cpp_file#close
+  cpp_file#close

+ 0 - 6
src/generators/cpp/gen/cppGenEnum.ml

@@ -1,11 +1,5 @@
-open Ast
 open Type
-open Error
-open Globals
 open CppStrings
-open CppExprUtils
-open CppTypeUtils
-open CppAst
 open CppAstTools
 open CppSourceWriter
 open CppContext

+ 0 - 6
src/generators/cpp/gen/cppReferences.ml

@@ -1,13 +1,7 @@
-open Ast
 open Type
-open Error
-open Globals
 open CppStrings
-open CppExprUtils
 open CppTypeUtils
-open CppAst
 open CppAstTools
-open CppSourceWriter
 open CppContext
 
 (*

+ 1 - 3
src/generators/gencpp.ml

@@ -22,9 +22,7 @@ open Type
 open Error
 open Globals
 open CppStrings
-open CppExprUtils
 open CppTypeUtils
-open CppAst
 open CppAstTools
 open CppSourceWriter
 open CppContext
@@ -399,4 +397,4 @@ let generate common_ctx =
    end else begin
       let ctx = new_context common_ctx debug_level (ref PMap.empty) (create_member_types common_ctx) in
       generate_source ctx
-   end
+   end

+ 1 - 1
src/generators/genhl.ml

@@ -390,7 +390,7 @@ let rec to_type ?tref ctx t =
 	| TType (td,tl) ->
 		let t =
 			get_rec_cache ctx t
-				(fun() -> abort "Unsupported recursive type" td.t_pos)
+				(fun() -> HDyn)
 				(fun tref -> to_type ~tref ctx (apply_typedef td tl))
 		in
 		(match td.t_path with

+ 0 - 1
src/generators/genswf.ml

@@ -24,7 +24,6 @@ open Error
 open Gctx
 open Ast
 open Globals
-open NativeLibraries
 
 let tag ?(ext=false) d = {
 	tid = 0;

+ 0 - 4
src/macro/eval/evalContext.ml

@@ -406,10 +406,6 @@ let exc_string_p str p = throw (vstring (EvalString.create_ascii str)) p
 
 let error_message = exc_string
 
-let flush_core_context f =
-	let ctx = get_ctx() in
-	ctx.curapi.MacroApi.flush_context f
-
 (* Environment handling *)
 
 let no_timer = fun () -> ()

+ 4 - 4
src/macro/eval/evalDebugSocket.ml

@@ -83,7 +83,7 @@ let var_to_json name value vio env =
 		| VInstance vi -> (rev_hash vi.iproto.ppath) ^ " {...}"
 		| VPrototype proto -> (s_proto_kind proto).sstring
 		| VFunction _ | VFieldClosure _ -> "<fun>"
-		| VLazy f -> level2_value_repr (!f())
+		| VLazy f -> level2_value_repr (Lazy.force f)
 		| VNativeString s -> string_repr s
 		| VHandle _ -> "<handle>"
 	in
@@ -148,7 +148,7 @@ let var_to_json name value vio env =
 			let fields = proto_fields proto in
 			jv "Anonymous" (s_proto_kind proto).sstring (List.length fields)
 		| VFunction _ | VFieldClosure _ -> jv "Function" "<fun>" 0
-		| VLazy f -> value_string (!f())
+		| VLazy f -> value_string (Lazy.force f)
 		| VNativeString s ->
 			jv "NativeString" (string_repr s) 0
 		| VHandle _ -> jv "Handle" "<handle>" 0
@@ -331,7 +331,7 @@ let output_inner_vars v env =
 				let n = rev_hash n in
 				n, v
 			) fields
-		| VLazy f -> loop (!f())
+		| VLazy f -> loop (Lazy.force f)
 	in
 	let children = loop v in
 	let vars = List.map (fun (n,v) -> var_to_json n v None env) children in
@@ -458,7 +458,7 @@ module ValueCompletion = struct
 				let fields = prototype_static_fields proto in
 				IntMap.fold (fun _ v acc -> v :: acc) fields []
 			| VLazy f ->
-				loop (!f())
+				loop (Lazy.force f)
 			| VEnumValue ve ->
 				begin match (get_static_prototype_raise (get_ctx()) ve.epath).pkind with
 					| PEnum names ->

+ 1 - 6
src/macro/eval/evalEncode.ml

@@ -316,12 +316,7 @@ let encode_ref v convert tostr =
 		ikind = IRef (Obj.repr v);
 	}
 
-let encode_lazy f =
-	let rec r = ref (fun () ->
-		let v = f() in
-		r := (fun () -> v);
-		v
-	) in
+let encode_lazy r =
 	VLazy r
 
 let encode_option encode_value o =

+ 1 - 1
src/macro/eval/evalMain.ml

@@ -361,7 +361,7 @@ let value_signature v =
 		| VHandle _ ->
 			custom_name 'H'
 		| VLazy f ->
-			loop (!f())
+			loop (Lazy.force f)
 	and loop_fields fields =
 		List.iter (fun (name,v) ->
 			adds (rev_hash name);

+ 4 - 4
src/macro/eval/evalMisc.ml

@@ -155,9 +155,9 @@ let rec compare a b =
 		if f1 != f2 then CUndef
 		else compare v1 v2
 	| VLazy f1,_ ->
-		compare (!f1()) b
+		compare (Lazy.force f1) b
 	| _,VLazy f2 ->
-		compare a (!f2())
+		compare a (Lazy.force f2)
 	| _ -> CUndef
 
 let rec arrays_equal cmp a1 a2 =
@@ -184,8 +184,8 @@ and equals_structurally a b =
 	| VObject a,VObject b -> a == b || arrays_equal equals_structurally a.ofields b.ofields
 	| VEnumValue a,VEnumValue b -> a == b || a.eindex = b.eindex && arrays_equal equals_structurally a.eargs b.eargs && a.epath = b.epath
 	| VPrototype proto1,VPrototype proto2 -> proto1.ppath = proto2.ppath
-	| VLazy f1,_ -> equals_structurally (!f1()) b
-	| _,VLazy f2 -> equals_structurally a (!f2())
+	| VLazy f1,_ -> equals_structurally (Lazy.force f1) b
+	| _,VLazy f2 -> equals_structurally a (Lazy.force f2)
 	| _ -> a == b
 
 let is_true v = match v with

+ 1 - 1
src/macro/eval/evalPrinting.ml

@@ -164,7 +164,7 @@ and s_value ?(indent_level=0) depth v =
 	| VInstance {ikind=IRegex r} -> r.r_rex_string
 	| VInstance i -> (try call_to_string () with Not_found -> s_hash i.iproto.ppath)
 	| VObject o -> (try call_to_string () with Not_found -> s_object (depth + 1) indent_level o)
-	| VLazy f -> s_value ~indent_level depth (!f())
+	| VLazy f -> s_value ~indent_level depth (Lazy.force f)
 	| VPrototype proto ->
 		try
 			call_to_string()

+ 1 - 1
src/macro/eval/evalStdLib.ml

@@ -3011,7 +3011,7 @@ module StdType = struct
 			| VEnumValue ve ->
 				7,[|get_static_prototype_as_value ctx ve.epath null_pos|]
 			| VLazy f ->
-				loop (!f())
+				loop (Lazy.force f)
 			| VInt64 _ | VUInt64 _ | VNativeString _ | VHandle _ -> 8,[||]
 		in
 		let i,vl = loop v in

+ 4 - 4
src/macro/eval/evalValue.ml

@@ -141,7 +141,7 @@ type value =
 	| VPrototype of vprototype
 	| VFunction of vfunc * bool
 	| VFieldClosure of value * vfunc
-	| VLazy of (unit -> value) ref
+	| VLazy of value Lazy.t
 	| VNativeString of string
 	| VHandle of vhandle
 	| VInt64 of Signed.Int64.t
@@ -323,8 +323,8 @@ let rec equals a b = match a,b with
 	| VFieldClosure(v1,f1),VFieldClosure(v2,f2) -> f1 == f2 && equals v1 v2
 	| VNativeString s1,VNativeString s2 -> s1 = s2
 	| VHandle h1,VHandle h2 -> same_handle h1 h2
-	| VLazy f1,_ -> equals (!f1()) b
-	| _,VLazy f2 -> equals a (!f2())
+	| VLazy f1,_ -> equals (Lazy.force f1) b
+	| _,VLazy f2 -> equals a (Lazy.force f2)
 	| _ -> a == b
 
 module ValueHashtbl = Hashtbl.Make(struct
@@ -354,5 +354,5 @@ let vnative_string s = VNativeString s
 let s_expr_pretty e = (Type.s_expr_pretty false "" false (Type.s_type (Type.print_context())) e)
 
 let rec vresolve v = match v with
-	| VLazy f -> vresolve (!f())
+	| VLazy f -> vresolve (Lazy.force f)
 	| _ -> v

+ 20 - 20
src/macro/macroApi.ml

@@ -39,7 +39,6 @@ type 'value compiler_api = {
 	resolve_complex_type : Ast.type_hint -> Ast.type_hint;
 	store_typed_expr : Type.texpr -> Ast.expr;
 	allow_package : string -> unit;
-	set_js_generator : (Genjs.ctx -> unit) -> unit;
 	get_local_type : unit -> t option;
 	get_expected_type : unit -> t option;
 	get_call_arguments : unit -> Ast.expr list option;
@@ -62,7 +61,6 @@ type 'value compiler_api = {
 	encode_expr : Ast.expr -> 'value;
 	encode_ctype : Ast.type_hint -> 'value;
 	decode_type : 'value -> t;
-	flush_context : (unit -> t) -> t;
 	info : ?depth:int -> string -> pos -> unit;
 	warning : ?depth:int -> Warning.warning -> string -> pos -> unit;
 	display_error : ?depth:int -> (string -> pos -> unit);
@@ -123,7 +121,7 @@ module type InterpApi = sig
 	val encode_array : value list -> value
 	val encode_string  : string -> value
 	val encode_obj : (string * value) list -> value
-	val encode_lazy : (unit -> value) -> value
+	val encode_lazy : value Lazy.t -> value
 
 	val vfun0 : (unit -> value) -> value
 	val vfun1 : (value -> value) -> value
@@ -171,8 +169,6 @@ module type InterpApi = sig
 
 	val value_string : value -> string
 
-	val flush_core_context : (unit -> t) -> t
-
 	val handle_decoding_error : (string -> unit) -> value -> Type.t -> (string * int) list
 
 	val get_api_call_pos : unit -> pos
@@ -413,7 +409,7 @@ and encode_display_kind dk =
 	| DKMarked -> 3, []
 	| DKPattern outermost -> 4, [vbool outermost]
 	in
-	encode_enum ~pos:None IDisplayKind tag pl
+	encode_enum IDisplayKind tag pl
 
 and encode_display_mode dm =
 	let tag, pl = match dm with
@@ -429,7 +425,7 @@ and encode_display_mode dm =
 		| DMModuleSymbols (Some s) -> 9, [(encode_string s)]
 		| DMSignature -> 10, []
 	in
-	encode_enum ~pos:None IDisplayMode tag pl
+	encode_enum IDisplayMode tag pl
 
 and encode_platform p =
 	let tag, pl = match p with
@@ -446,7 +442,7 @@ and encode_platform p =
 		| Eval -> 10, []
 		| CustomTarget s -> 11, [(encode_string s)]
 	in
-	encode_enum ~pos:None IPlatform tag pl
+	encode_enum IPlatform tag pl
 
 and encode_platform_config pc =
 	encode_obj [
@@ -474,7 +470,7 @@ and encode_capture_policy cp =
 		| CPWrapRef -> 1
 		| CPLoopVars -> 2
 	in
-	encode_enum ~pos:None ICapturePolicy tag []
+	encode_enum ICapturePolicy tag []
 
 and encode_var_scoping_config vsc =
 	encode_obj [
@@ -487,7 +483,7 @@ and encode_var_scope vs =
 		| FunctionScope -> 0
 		| BlockScope -> 1
 	in
-	encode_enum ~pos:None IVarScope tag []
+	encode_enum IVarScope tag []
 
 and encode_var_scoping_flags vsf =
 	let tag, pl = match vsf with
@@ -500,7 +496,7 @@ and encode_var_scoping_flags vsf =
 		| ReserveNames (names) -> 6, [encode_array (List.map encode_string names)]
 		| SwitchCasesNoBlocks -> 7, []
 	in
-	encode_enum ~pos:None IVarScopingFlags tag pl
+	encode_enum IVarScopingFlags tag pl
 
 and encode_exceptions_config ec =
 	encode_obj [
@@ -517,7 +513,7 @@ and encode_package_rule pr =
 		| Forbidden -> 0, []
 		| Remap (path) -> 2, [encode_string path]
 	in
-	encode_enum ~pos:None IPackageRule tag pl
+	encode_enum IPackageRule tag pl
 
 and encode_message cm =
 	let tag, pl = match cm.cm_severity with
@@ -525,7 +521,7 @@ and encode_message cm =
 		| Warning | Hint -> 1, [(encode_string cm.cm_message); (encode_pos cm.cm_pos)]
 		| Error -> Globals.die "" __LOC__
 	in
-	encode_enum ~pos:None IMessage tag pl
+	encode_enum IMessage tag pl
 
 and encode_efield_kind efk =
 	let i = match efk with
@@ -631,7 +627,7 @@ and encode_expr e =
 			"expr", encode_enum IExpr tag pl;
 		]
 	in
-	encode_lazy (fun () -> loop e)
+	encode_lazy (lazy (loop e))
 
 and encode_null_expr e =
 	match e with
@@ -756,7 +752,7 @@ let rec decode_ast_path t =
 	let p_full = field t "pos" in
 	let p_full = if p_full = vnull then Globals.null_pos else decode_pos p_full in
 	let p_path = field t "posPath" in
-	let p_path = if p_path = vnull then Globals.null_pos else decode_pos p_path in
+	let p_path = if p_path = vnull then p_full else decode_pos p_path in
 	make_ptp (mk_type_path ~params ?sub (pack,name)) ~p_path p_full
 
 and decode_tparam v =
@@ -1097,7 +1093,7 @@ and encode_cfield f =
 		"params", encode_type_params f.cf_params;
 		"meta", encode_meta f.cf_meta (fun m -> f.cf_meta <- m);
 		"expr", vfun0 (fun() ->
-			ignore (flush_core_context (fun() -> follow f.cf_type));
+			ignore (follow f.cf_type);
 			(match f.cf_expr with None -> vnull | Some e -> encode_texpr e)
 		);
 		"kind", encode_field_kind f.cf_kind;
@@ -1264,8 +1260,7 @@ and encode_lazy_type t =
 					| LAvailable t ->
 						encode_type t
 					| LWait _ ->
-						(* we are doing some typing here, let's flush our context if it's not already *)
-						encode_type (flush_core_context (fun() -> lazy_type f))
+						encode_type (lazy_type f)
 					| LProcessing _ ->
 						(* our type in on the processing stack, error instead of returning most likely an unbound mono *)
 						error_message "Accessing a type while it's being typed");
@@ -2012,8 +2007,7 @@ let macro_api ccom get_api =
 		);
 		"set_custom_js_generator", vfun1 (fun f ->
 			let f = prepare_callback f 1 in
-			(get_api()).set_js_generator (fun js_ctx ->
-				let com = Common.to_gctx (ccom()) in
+			let gen com js_ctx =
 				Genjs.setup_kwds com;
 				let api = encode_obj [
 					"outputFile", encode_string com.file;
@@ -2060,6 +2054,12 @@ let macro_api ccom get_api =
 					);
 				] in
 				ignore(f [api]);
+			in
+			let com = ccom() in
+			com.js_gen <- Some (fun() ->
+				Path.mkdir_from_path com.file;
+				let js_ctx = Genjs.alloc_ctx (Common.to_gctx com) (Gctx.get_es_version com.defines) in
+				gen (Common.to_gctx com) js_ctx;
 			);
 			vnull
 		);

+ 1 - 1
src/optimization/inline.ml

@@ -912,7 +912,7 @@ and inline_rest_params ctx f params map_type p =
 						in
 						let array = mk (TArrayDecl params) (ctx.t.tarray t_params) p in
 						(* haxe.Rest.of(array) *)
-						let e = make_static_call ctx c cf (apply_params a.a_params [t]) [array] (TAbstract(a,[t_params])) p in
+						let e =CallUnification.make_static_call_better ctx c cf [t] [array] (TAbstract(a,[t_params])) p in
 						[e]
 					| _ ->
 						die ~p:v.v_pos "Unexpected rest arguments type" __LOC__

+ 6 - 1
src/syntax/reification.ml

@@ -123,6 +123,8 @@ let reify in_macro =
 					("name", (efield(ei,"name"),p));
 					("sub", (efield(ei,"sub"),p));
 					("params", ea);
+					("pos", to_pos p);
+					("posPath", to_pos ptp.pos_path);
 				] in
 				to_obj fields p
 		end else begin
@@ -130,8 +132,11 @@ let reify in_macro =
 				("pack", to_array to_string t.tpackage p);
 				("name", to_string t.tname p);
 				("params", to_array to_tparam t.tparams p);
+				("pos", to_pos p);
+				("posPath", to_pos ptp.pos_path);
 			] in
-			to_obj (match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p]) p
+			let fields = match t.tsub with None -> fields | Some s -> fields @ ["sub",to_string s p] in
+			to_obj fields p
 		end
 	and to_ctype t p =
 		let ct n vl = mk_enum "ComplexType" n vl p in

+ 12 - 0
src/typing/callUnification.ml

@@ -655,3 +655,15 @@ let maybe_reapply_overload_call ctx e =
 			end
 		| _ ->
 			e
+
+let make_static_call_better ctx c cf tl el t p =
+	let fh = match c.cl_kind with
+		| KAbstractImpl a when has_class_field_flag cf CfImpl ->
+			FHAbstract(a,tl,c)
+		| _ ->
+			FHStatic c
+	in
+	let e1 = Builder.make_static_this c p in
+	let fa = FieldAccess.create e1 cf fh false p in
+	let fcc = unify_field_call ctx fa el [] p false in
+	fcc.fc_data()

+ 1 - 1
src/typing/fields.ml

@@ -386,7 +386,7 @@ let type_field cfg ctx e i p mode (with_type : WithType.t) =
 					ctx.e.monomorphs.perfunction <- (r,p) :: ctx.e.monomorphs.perfunction;
 				let f = mk_field() in
 				Monomorph.add_down_constraint r (MField f);
-				Monomorph.add_down_constraint r MOpenStructure;
+				Monomorph.add_modifier r MOpenStructure;
 				field_access f FHAnon
 			| CMixed l ->
 				let rec loop_constraints l =

+ 15 - 8
src/typing/finalization.ml

@@ -8,24 +8,31 @@ open Typecore
 (* ---------------------------------------------------------------------- *)
 (* FINALIZATION *)
 
-let get_main ctx types =
-	match ctx.com.main.main_class with
-	| None -> None
+let maybe_load_main tctx = match tctx.com.main.main_class with
 	| Some path ->
+		Some (Typeload.load_module tctx path null_pos)
+	| None ->
+		None
+
+
+let get_main ctx main_module types =
+	match main_module with
+	| None -> None
+	| Some main_module ->
 		let p = null_pos in
+		let path = main_module.m_path in
 		let pack,name = path in
-		let m = Typeload.load_module ctx (pack,name) p in
 		let c,f =
 			let p = ref p in
 			try
-				match m.m_statics with
+				match main_module.m_statics with
 				| None ->
 					raise Not_found
 				| Some c ->
 					p := c.cl_name_pos;
 					c, PMap.find "main" c.cl_statics
 			with Not_found -> try
-				let t = Typeload.find_type_in_module_raise ctx m name null_pos in
+				let t = Typeload.find_type_in_module_raise ctx main_module name null_pos in
 				match t with
 				| TEnumDecl _ | TTypeDecl _ | TAbstractDecl _ ->
 					raise_typing_error ("Invalid -main : " ^ s_type_path path ^ " is not a class") null_pos
@@ -196,6 +203,6 @@ let sort_types com (modules : module_lut) =
 	List.iter (fun m -> List.iter loop m.m_types) sorted_modules;
 	List.rev !types, sorted_modules
 
-let generate ctx =
+let generate ctx main_class =
 	let types,modules = sort_types ctx.com ctx.com.module_lut in
-	get_main ctx types,types,modules
+	get_main ctx main_class types,types,modules

+ 4 - 3
src/typing/forLoop.ml

@@ -88,7 +88,8 @@ module IterationKind = struct
 		(mk (TArray (arr,iexpr)) pt p)
 
 	let check_iterator ?(resume=false) ?last_resort ctx s e p =
-		let t,pt = Typeload.t_iterator ctx p in
+		let pt = spawn_monomorph ctx.e p in
+		let t = ctx.t.titerator pt in
 		let dynamic_iterator = ref None in
 		let e1 = try
 			let e = AbstractCast.cast_or_unify_raise ctx t e p in
@@ -143,7 +144,7 @@ module IterationKind = struct
 		| TAbstract({a_impl = Some c} as a,tl) ->
 			let cf_length = PMap.find "get_length" c.cl_statics in
 			let get_length e p =
-				make_static_call ctx c cf_length (apply_params a.a_params tl) [e] ctx.com.basic.tint p
+				CallUnification.make_static_call_better ctx c cf_length tl [e] ctx.com.basic.tint p
 			in
 			(match follow cf_length.cf_type with
 				| TFun(_,tr) ->
@@ -159,7 +160,7 @@ module IterationKind = struct
 				let todo = mk (TConst TNull) ctx.t.tint p in
 				let cf,_,r,_ = AbstractCast.find_array_read_access_raise ctx a tl todo p in
 				let get_next e_base e_index t p =
-					make_static_call ctx c cf (apply_params a.a_params tl) [e_base;e_index] r p
+					CallUnification.make_static_call_better ctx c cf tl [e_base;e_index] r p
 				in
 				IteratorCustom(get_next,get_length),e,r
 			with Not_found ->

+ 13 - 20
src/typing/macroContext.ml

@@ -22,7 +22,6 @@ open DisplayTypes.DisplayMode
 open Common
 open Type
 open Typecore
-open Resolution
 open Error
 open Globals
 
@@ -200,23 +199,11 @@ let make_macro_com_api com mcom p =
 		type_expr = (fun e ->
 			Interp.exc_string "unsupported"
 		);
-		flush_context = (fun f ->
-			Interp.exc_string "unsupported"
-		);
 		store_typed_expr = (fun te ->
 			let p = te.epos in
 			snd (Typecore.store_typed_expr com te p)
 		);
 		allow_package = (fun v -> Common.allow_package com v);
-		set_js_generator = (fun gen ->
-			com.js_gen <- Some (fun() ->
-				Path.mkdir_from_path com.file;
-				let js_ctx = Genjs.alloc_ctx (Common.to_gctx com) (Gctx.get_es_version com.defines) in
-				let t = macro_timer com ["jsGenerator"] in
-				gen js_ctx;
-				t()
-			);
-		);
 		get_local_type = (fun() ->
 			Interp.exc_string "unsupported"
 		);
@@ -417,9 +404,6 @@ let make_macro_api ctx mctx p =
 		MacroApi.type_expr = (fun e ->
 			typing_timer ctx true (fun ctx -> type_expr ctx e WithType.value)
 		);
-		MacroApi.flush_context = (fun f ->
-			typing_timer ctx true (fun _ -> f ())
-		);
 		MacroApi.get_local_type = (fun() ->
 			match ctx.c.get_build_infos() with
 			| Some (mt,tl,_) ->
@@ -506,7 +490,13 @@ let make_macro_api ctx mctx p =
 			let mpath = Ast.parse_path m in
 			begin try
 				let m = ctx.com.module_lut#find mpath in
-				ignore(TypeloadModule.type_types_into_module ctx.com ctx.g m types pos)
+				if m != ctx.m.curmod then begin
+					let pos = { pfile = (Path.UniqueKey.lazy_path m.m_extra.m_file); pmin = 0; pmax = 0 } in
+					raise_typing_error_ext (make_error ~sub:[
+						make_error ~depth:1 (Custom "Previously defined here") pos
+					] (Custom (Printf.sprintf "Cannot redefine module %s" (s_type_path mpath))) p);
+				end else
+					ignore(TypeloadModule.type_types_into_module ctx.com ctx.g m types pos)
 			with Not_found ->
 				let mnew = TypeloadModule.type_module ctx.com ctx.g mpath (ctx.com.file_keys#generate_virtual ctx.com.compilation_step) types pos in
 				mnew.m_extra.m_kind <- MFake;
@@ -602,15 +592,17 @@ let init_macro_interp mctx mint =
 and flush_macro_context mint mctx =
 	let t = macro_timer mctx.com ["flush"] in
 	let mctx = (match mctx.g.macros with None -> die "" __LOC__ | Some (_,mctx) -> mctx) in
+	let main_module = Finalization.maybe_load_main mctx in
 	Finalization.finalize mctx;
-	let _, types, modules = Finalization.generate mctx in
+	let _, types, modules = Finalization.generate mctx main_module in
 	mctx.com.types <- types;
 	mctx.com.Common.modules <- modules;
+	let ectx = Exceptions.create_exception_context mctx in
 	(* we should maybe ensure that all filters in Main are applied. Not urgent atm *)
 	let expr_filters = [
 		"handle_abstract_casts",AbstractCast.handle_abstract_casts;
 		"local_statics",LocalStatic.run;
-		"Exceptions",Exceptions.filter;
+		"Exceptions",(fun _ -> Exceptions.filter ectx);
 		"captured_vars",(fun _ -> CapturedVars.captured_vars mctx.com);
 	] in
 	(*
@@ -655,7 +647,7 @@ and flush_macro_context mint mctx =
 	in
 	let type_filters = [
 		FiltersCommon.remove_generic_base;
-		Exceptions.patch_constructors mctx;
+		Exceptions.patch_constructors mctx ectx;
 		(fun mt -> AddFieldInits.add_field_inits mctx.c.curclass.cl_path (RenameVars.init mctx.com) mctx.com mt);
 		Filters.update_cache_dependencies ~close_monomorphs:false mctx.com;
 		minimal_restore;
@@ -702,6 +694,7 @@ let create_macro_interp api mctx =
 
 let create_macro_context com =
 	let com2 = Common.clone com true in
+	enter_stage com2 CInitMacrosDone;
 	com.get_macros <- (fun() -> Some com2);
 	com2.package_rules <- PMap.empty;
 	(* Inherit most display settings, but require normal typing. *)

+ 1 - 1
src/typing/nullSafety.ml

@@ -72,7 +72,7 @@ let is_string_type t =
 *)
 let rec is_nullable_type ?(dynamic_is_nullable=false) = function
 	| TMono r ->
-		(match r.tm_type with None -> false | Some t -> is_nullable_type t)
+		(match r.tm_type with None -> is_nullable_mono r | Some t -> is_nullable_type t)
 	| TAbstract ({ a_path = ([],"Null") },[t]) ->
 		true
 	| TAbstract ({ a_path = ([],"Any") },[]) ->

+ 2 - 2
src/typing/operators.ml

@@ -434,11 +434,11 @@ let find_abstract_binop_overload ctx op e1 e2 a c tl left is_assign_op p =
 			let vr = new value_reference ctx in
 			let e2' = vr#as_var "lhs" e2 in
 			let e1' = vr#as_var "rhs" e1 in
-			let e = make_static_call ctx c cf map [e1';e2'] tret p in
+			let e = CallUnification.make_static_call_better ctx c cf tl [e1';e2'] tret p in
 			let e = vr#to_texpr e in
 			BinopResult.create_special e needs_assign
 		end else
-			BinopResult.create_special (make_static_call ctx c cf map [e1;e2] tret p) needs_assign
+			BinopResult.create_special (make_static_call_better ctx c cf tl [e1;e2] tret p) needs_assign
 	in
 	(* special case for == and !=: if the second type is a monomorph, assume that we want to unify
 		it with the first type to preserve comparison semantics. *)

+ 3 - 9
src/typing/typeload.ml

@@ -112,14 +112,7 @@ let find_type_in_current_module_context ctx pack name =
 			ImportHandling.mark_import_position ctx pi;
 			t
 	end else begin
-		(* All this is very weird *)
-		try
-			List.find (fun mt -> t_path mt = (pack,name)) ctx.m.curmod.m_types
-		with Not_found ->
-			(* see also https://github.com/HaxeFoundation/haxe/issues/9150 *)
-			let t,pi = ctx.m.import_resolution#find_type_import_weirdly pack name in
-			ImportHandling.mark_import_position ctx pi;
-		t
+		List.find (fun mt -> t_path mt = (pack,name)) ctx.m.curmod.m_types
 	end
 
 let find_in_wildcard_imports ctx mname p f =
@@ -402,7 +395,7 @@ and load_instance' ctx ptp get_params mode =
 		if t.tparams <> [] then raise_typing_error ("Class type parameter " ^ t.tname ^ " can't have parameters") ptp.pos_full;
 		pt
 	with Not_found ->
-		let mt = load_type_def ctx (if ptp.pos_path == null_pos then ptp.pos_full else ptp.pos_path) t in
+		let mt = load_type_def ctx ptp.pos_path t in
 		let info = ctx.g.get_build_info ctx mt ptp.pos_full in
 		if info.build_path = ([],"Dynamic") then match t.tparams with
 			| [] -> t_dynamic
@@ -788,6 +781,7 @@ let load_core_class ctx c =
 	let ctx2 = (match ctx.g.core_api with
 		| None ->
 			let com2 = Common.clone ctx.com ctx.com.is_macro_context in
+			enter_stage com2 CInitMacrosDone;
 			com2.defines.Define.values <- PMap.empty;
 			Common.define com2 Define.CoreApi;
 			Common.define com2 Define.Sys;

+ 1 - 3
src/typing/typer.ml

@@ -399,9 +399,7 @@ let rec type_ident_raise ctx i p mode with_type =
 				| WithType.WithType(t,_) ->
 					begin match follow t with
 					| TMono r when not (is_nullable t) ->
-						(* If our expected type is a monomorph, bind it to Null<?>. The is_nullable check is here because
-							the expected type could already be Null<?>, in which case we don't want to double-wrap (issue #11286). *)
-						Monomorph.do_bind r (tnull())
+						Monomorph.add_modifier r (MNullable ctx.t.tnull)
 					| _ ->
 						(* Otherwise there's no need to create a monomorph, we can just type the null literal
 						the way we expect it. *)

+ 8 - 1
src/typing/typerEntry.ml

@@ -107,7 +107,14 @@ let create com macros =
 				in
 				ctx.t.tnull <- mk_null;
 			| _ -> ())
-		| TEnumDecl _ | TClassDecl _ | TTypeDecl _ ->
+		| TTypeDecl td ->
+			begin match snd td.t_path with
+			| "Iterator" ->
+				ctx.t.titerator <- (fun t -> TType(td,[t]))
+			| _ ->
+				()
+			end
+		| TEnumDecl _ | TClassDecl _ ->
 			()
 	) ctx.g.std_types.m_types;
 	let m = TypeloadModule.load_module ctx ([],"String") null_pos in

+ 10 - 0
std/haxe/macro/Expr.hx

@@ -670,6 +670,16 @@ typedef TypePath = {
 		`pack.Module.Type` has `name = "Module"`, `sub = "Type"`, if available.
 	**/
 	var ?sub:String;
+
+	/**
+		The full position of the type path, including type parameters.
+	**/
+	var ?pos:Position;
+
+	/**
+		The position of the dot-path itself, without type parameters.
+	**/
+	var ?posPath:Position;
 }
 
 /**

+ 2 - 2
std/hl/types/ArrayBytes.hx

@@ -302,14 +302,14 @@ class BytesIterator<T> extends ArrayIterator<T> {
 
 	override function getDyn(pos:Int):Dynamic {
 		var pos:UInt = pos;
-		if (pos >= length)
+		if (pos >= (length : UInt))
 			return bytes.nullValue;
 		return bytes[pos];
 	}
 
 	override function setDyn(pos:Int, v:Dynamic) {
 		var pos:UInt = pos;
-		if (pos >= length)
+		if (pos >= (length : UInt))
 			__expand(pos);
 		bytes[pos] = v;
 	}

+ 2 - 2
std/hl/types/ArrayObj.hx

@@ -325,14 +325,14 @@ class ArrayObj<T> extends ArrayBase {
 
 	override function getDyn(pos:Int):Dynamic {
 		var pos:UInt = pos;
-		if (pos >= length)
+		if (pos >= (length : UInt))
 			return null;
 		return array[pos];
 	}
 
 	override function setDyn(pos:Int, v:Dynamic) {
 		var pos:UInt = pos;
-		if (pos >= length)
+		if (pos >= (length : UInt))
 			__expand(pos);
 		array[pos] = Api.safeCast(v, array.getType());
 	}

+ 10 - 0
tests/misc/projects/Issue11431/Main.hx

@@ -0,0 +1,10 @@
+import haxe.macro.Expr;
+
+macro function makeCt() {
+	var ct = macro :NotExists<String>;
+	return macro(e : $ct);
+}
+
+function main() {
+	makeCt();
+}

+ 2 - 0
tests/misc/projects/Issue11431/compile-fail.hxml

@@ -0,0 +1,2 @@
+--main Main
+--interp

+ 1 - 0
tests/misc/projects/Issue11431/compile-fail.hxml.stderr

@@ -0,0 +1 @@
+Main.hx:4: characters 18-27 : Type not found : NotExists 

+ 1 - 1
tests/misc/projects/Issue11624/compile-bar-fail.hxml.stderr

@@ -1,5 +1,5 @@
 MainBar.hx:6: characters 18-21 : Field bar has different type than in Foo
 MainBar.hx:2: characters 11-14 : ... Interface field is defined here
 MainBar.hx:6: characters 18-21 : ... error: Null<Unknown<0>> should be bar.T
-MainBar.hx:6: characters 18-21 : ... have: (...) -> Null<...>
+MainBar.hx:6: characters 18-21 : ... have: (...) -> Null<Unknown<0>>
 MainBar.hx:6: characters 18-21 : ... want: (...) -> bar.T

+ 1 - 1
tests/misc/projects/Issue11624/compile-foo-fail.hxml.stderr

@@ -1,5 +1,5 @@
 MainFoo.hx:6: characters 18-21 : Field foo has different type than in Foo
 MainFoo.hx:2: characters 11-14 : ... Interface field is defined here
 MainFoo.hx:6: characters 18-21 : ... error: Null<Unknown<0>> should be foo.T
-MainFoo.hx:6: characters 18-21 : ... have: (...) -> Null<...>
+MainFoo.hx:6: characters 18-21 : ... have: (...) -> Null<Unknown<0>>
 MainFoo.hx:6: characters 18-21 : ... want: (...) -> foo.T

+ 2 - 0
tests/misc/projects/Issue11632/compile-test.hxml.stdout

@@ -5,6 +5,8 @@
 		name: Null
 		pack: []
 		params: [TPType(null <- expected enum value)]
+		pos: null
+		posPath: null
 		sub: null
 	}), null)
 	meta: null

+ 31 - 0
tests/misc/projects/Issue11753/Main.hx

@@ -0,0 +1,31 @@
+class Main {
+	static var doThings : Foo -> Void;
+
+	static function main() {
+		var foo = new Foo();
+		doThings = (foo -> doThingsImpl(foo));
+		doThings(foo);
+	}
+
+	static function doThingsImpl(foo) {
+		foo.doWithBar();
+		$type(foo);
+		$type(foo.doWithBar);
+
+		if (foo != null) trace(foo);
+		$type(foo);
+		$type(foo.doWithBar);
+	}
+}
+
+class Foo {
+	public function new() {}
+	public function doWithBar(?bar:Bar) {
+		trace(bar);
+	}
+}
+
+@:keep
+class Bar {
+	public function new() {}
+}

+ 28 - 0
tests/misc/projects/Issue11753/Main2.hx

@@ -0,0 +1,28 @@
+class Foo {
+	public function new() {}
+
+	public function test() {}
+
+	public function doWithBar(?bar:Bar) {
+		trace(bar);
+	}
+}
+
+@:keep
+class Bar {
+	public function new() {}
+}
+
+function doThingsImpl(foo) {
+	$type(foo); // Unknown<0>
+	foo.doWithBar();
+	$type(foo); // Unknown<0> : { doWithBar : () -> Unknown<1> }
+	$type(foo.doWithBar); // () -> Unknown<0>
+	if (foo != null)
+		trace(foo);
+	$type(foo); // Null<{ doWithBar : () -> Unknown<0> }>
+	$type(foo.doWithBar); // () -> Unknown<0>
+	foo.test(); // Null<{ doWithBar : () -> Unknown<0> }> has no field test
+}
+
+function main() {}

+ 4 - 0
tests/misc/projects/Issue11753/compile-fail.hxml

@@ -0,0 +1,4 @@
+-main Main
+--hl bin/main.hl
+-D message.reporting=pretty
+-D message.no-color

+ 32 - 0
tests/misc/projects/Issue11753/compile-fail.hxml.stderr

@@ -0,0 +1,32 @@
+[WARNING] Main.hx:12: characters 9-12
+
+ 12 |   $type(foo);
+    |         ^^^
+    | Unknown<0> : { doWithBar : () -> Unknown<1> }
+
+[WARNING] Main.hx:13: characters 9-22
+
+ 13 |   $type(foo.doWithBar);
+    |         ^^^^^^^^^^^^^
+    | () -> Unknown<0>
+
+[WARNING] Main.hx:16: characters 9-12
+
+ 16 |   $type(foo);
+    |         ^^^
+    | Null<Unknown<0> : { doWithBar : () -> Unknown<1> }>
+
+[WARNING] Main.hx:17: characters 9-22
+
+ 17 |   $type(foo.doWithBar);
+    |         ^^^^^^^^^^^^^
+    | () -> Unknown<0>
+
+[ERROR] Main.hx:6: characters 35-38
+
+  6 |   doThings = (foo -> doThingsImpl(foo));
+    |                                   ^^^
+    | error: (?bar : Null<Bar>) -> Void should be () -> Unknown<0>
+    | have: { doWithBar: (?...) -> ... }
+    | want: { doWithBar: () -> ... }
+

+ 4 - 0
tests/misc/projects/Issue11753/compile.hxml

@@ -0,0 +1,4 @@
+-main Main2
+--hl bin/main.hl
+-D message.reporting=pretty
+-D message.no-color

+ 29 - 0
tests/misc/projects/Issue11753/compile.hxml.stderr

@@ -0,0 +1,29 @@
+[WARNING] Main2.hx:17: characters 8-11
+
+ 17 |  $type(foo); // Unknown<0>
+    |        ^^^
+    | Unknown<0>
+
+[WARNING] Main2.hx:19: characters 8-11
+
+ 19 |  $type(foo); // Unknown<0> : { doWithBar : () -> Unknown<1> }
+    |        ^^^
+    | Unknown<0> : { doWithBar : () -> Unknown<1> }
+
+[WARNING] Main2.hx:20: characters 8-21
+
+ 20 |  $type(foo.doWithBar); // () -> Unknown<0>
+    |        ^^^^^^^^^^^^^
+    | () -> Unknown<0>
+
+[WARNING] Main2.hx:23: characters 8-11
+
+ 23 |  $type(foo); // Null<{ doWithBar : () -> Unknown<0> }>
+    |        ^^^
+    | Null<Unknown<0> : { doWithBar : () -> Unknown<1> }>
+
+[WARNING] Main2.hx:24: characters 8-21
+
+ 24 |  $type(foo.doWithBar); // () -> Unknown<0>
+    |        ^^^^^^^^^^^^^
+    | () -> Unknown<0>

+ 3 - 0
tests/misc/projects/Issue5456/Main.hx

@@ -0,0 +1,3 @@
+function main() {
+	trace(new Test().c);
+}

+ 16 - 0
tests/misc/projects/Issue5456/Test.hx

@@ -0,0 +1,16 @@
+package;
+
+import test.C;
+
+@:build(TestBuilder.build())
+class Test extends B {
+	public function new() {
+		super();
+	}
+}
+
+class B {
+	public var c:Int = C.func();
+
+	public function new() {}
+}

+ 20 - 0
tests/misc/projects/Issue5456/TestBuilder.hx

@@ -0,0 +1,20 @@
+package;
+
+import haxe.macro.Context;
+import haxe.macro.Expr;
+import haxe.macro.Type;
+
+class TestBuilder {
+	public static function build():Array<Field> {
+		var fields:Array<Field> = Context.getBuildFields();
+		var classType:ClassType;
+		switch (Context.getLocalType()) {
+			case TInst(r, _):
+				classType = r.get();
+			case _:
+		}
+		classType.superClass.t.get().fields.get();
+
+		return fields;
+	}
+}

+ 2 - 0
tests/misc/projects/Issue5456/compile.hxml

@@ -0,0 +1,2 @@
+--main Main
+--interp

+ 1 - 0
tests/misc/projects/Issue5456/compile.hxml.stdout

@@ -0,0 +1 @@
+Main.hx:2: 0

+ 7 - 0
tests/misc/projects/Issue5456/test/C.hx

@@ -0,0 +1,7 @@
+package test;
+
+class C {
+	public static function func():Int {
+		return 0;
+	}
+}

+ 3 - 0
tests/misc/projects/Issue6321/A.hx

@@ -0,0 +1,3 @@
+class A {
+    public var a:Int;
+}

+ 4 - 0
tests/misc/projects/Issue6321/B.hx

@@ -0,0 +1,4 @@
+class B {
+    var a:A;
+    function b() a.a;
+}

+ 14 - 0
tests/misc/projects/Issue6321/Macro.hx

@@ -0,0 +1,14 @@
+class Macro {
+	static function doStuff() {
+		haxe.macro.Context.onAfterInitMacros(() -> {
+			switch (haxe.macro.Context.getType("B")) {
+				case TInst(_.get() => cl, _):
+					for (field in cl.fields.get()) {
+						trace(field.name, field.expr()?.pos);
+					}
+				default:
+					throw false;
+			}
+		});
+	}
+}

+ 12 - 0
tests/misc/projects/Issue6321/MacroFail.hx

@@ -0,0 +1,12 @@
+class MacroFail {
+	static function doStuff() {
+		switch (haxe.macro.Context.getType("B")) {
+			case TInst(_.get() => cl, _):
+				for (field in cl.fields.get()) {
+					trace(field.name, field.expr()?.pos);
+				}
+			default:
+				throw false;
+		}
+	}
+}

+ 1 - 0
tests/misc/projects/Issue6321/compile-fail.hxml

@@ -0,0 +1 @@
+--macro "MacroFail.doStuff()"

+ 2 - 0
tests/misc/projects/Issue6321/compile-fail.hxml.stderr

@@ -0,0 +1,2 @@
+MacroFail.hx:3: characters 11-42 : Cannot use this API from initialization macros.
+MacroFail.hx:3: characters 11-42 : ... Use `Context.onAfterInitMacros` to register a callback to run when context is ready.

+ 1 - 0
tests/misc/projects/Issue6321/compile.hxml

@@ -0,0 +1 @@
+--macro "Macro.doStuff()"

+ 2 - 0
tests/misc/projects/Issue6321/compile.hxml.stdout

@@ -0,0 +1,2 @@
+Macro.hx:7: a,null
+Macro.hx:7: b,#pos(B.hx:3: characters 18-21)

+ 7 - 0
tests/misc/projects/Issue6321/test/C.hx

@@ -0,0 +1,7 @@
+package test;
+
+class C {
+	public static function func():Int {
+		return 0;
+	}
+}

+ 12 - 0
tests/unit/src/unit/issues/Issue11810.hx

@@ -0,0 +1,12 @@
+package unit.issues;
+
+class Issue11810 extends Test {
+	#if hl
+	function test() {
+		var arrObj = [];
+		eq(null, arrObj[arrObj.length-1]);
+		var arrBytes : Array<Int> = [];
+		eq(0, arrBytes[arrBytes.length-1]);
+	}
+	#end
+}

+ 0 - 11
tests/unit/src/unit/issues/Issue3024.hx

@@ -1,13 +1,5 @@
 package unit.issues;
 
-#if hl
-
-// no support for recursive types atm
-class Issue3024 extends Test {
-}
-
-#else
-
 import haxe.ds.StringMap;
 import haxe.ds.Vector;
 
@@ -16,7 +8,6 @@ private typedef MyMap = StringMap<MyFunction>;
 private typedef MyFunction = MyVector->MyMap->Dynamic;
 
 class Issue3024 extends Test {
-
 	private var myVector:MyVector;
 
 	private var myMap:MyMap;
@@ -31,5 +22,3 @@ class Issue3024 extends Test {
 		this.myMap = myMap;
 	}
 }
-
-#end

+ 19 - 15
tests/unit/src/unit/issues/misc/Issue3183Macro.hx

@@ -1,7 +1,7 @@
 package unit.issues.misc;
 
-import haxe.macro.Expr;
 import haxe.macro.Context;
+import haxe.macro.Expr;
 import haxe.macro.Type;
 
 using haxe.macro.Tools;
@@ -10,7 +10,7 @@ class Issue3183Macro {
 	static var tupleMap = new Map();
 
 	macro static public function buildTuple():ComplexType {
-		switch(Context.getLocalType()) {
+		switch (Context.getLocalType()) {
 			case TInst(c, args):
 				var arity = args.length;
 				if (arity == 0) {
@@ -26,21 +26,23 @@ class Issue3183Macro {
 					tupleMap[arity] = buildTupleType(c.get(), Context.getBuildFields(), arity);
 				}
 				var ct = tupleMap[arity];
-				ct.params = [for (t in args) {
-					switch (t) {
-						case TInst(_.get().kind => KExpr(e), _):
-							TPType(Context.typeof(e).toComplexType());
-						case _:
-							TPType(t.toComplexType());
+				ct.params = [
+					for (t in args) {
+						switch (t) {
+							case TInst(_.get().kind => KExpr(e), _):
+								TPType(Context.typeof(e).toComplexType());
+							case _:
+								TPType(t.toComplexType());
+						}
 					}
-				}];
+				];
 				return TPath(ct);
 			case _:
 				return Context.error("Class expected", Context.currentPos());
 		}
 	}
 
-	static function buildTupleType(c:ClassType, fields:Array<Field>, arity:Int) {
+	static function buildTupleType(c:ClassType, fields:Array<Field>, arity:Int):TypePath {
 		var typeParams = [];
 		var tupleFields = [];
 		for (i in 0...arity) {
@@ -70,10 +72,12 @@ class Issue3183Macro {
 			access: [APublic, AInline],
 			kind: FFun({
 				ret: null,
-				expr: macro $b{tupleFields.map(function(field) {
-					var name = field.name;
-					return macro this.$name = $i{name};
-				})},
+				expr: macro $b{
+					tupleFields.map(function(field) {
+						var name = field.name;
+						return macro this.$name = $i{name};
+					})
+				},
 				params: [],
 				args: tupleFields.map(function(field) {
 					return {
@@ -103,4 +107,4 @@ class Issue3183Macro {
 			sub: null
 		}
 	}
-}
+}