瀏覽代碼

Merge branch 'development' into haxe.Unit

Simon Krajewski 5 月之前
父節點
當前提交
57a748a357
共有 100 個文件被更改,包括 582 次插入283 次删除
  1. 5 0
      .github/workflows/main.yml
  2. 1 0
      extra/github-actions/test-mac.yml
  3. 6 0
      extra/github-actions/test-windows.yml
  4. 2 0
      extra/github-actions/workflows/main.yml
  5. 1 1
      src/compiler/compiler.ml
  6. 1 1
      src/core/ast.ml
  7. 64 51
      src/filters/filters.ml
  8. 1 1
      src/generators/cpp/gen/cppCppia.ml
  9. 18 11
      src/generators/genhl.ml
  10. 12 11
      src/generators/hl2c.ml
  11. 6 6
      src/optimization/dce.ml
  12. 20 3
      src/syntax/grammar.ml
  13. 4 1
      src/typing/macroContext.ml
  14. 32 16
      src/typing/nullSafety.ml
  15. 14 3
      src/typing/typeload.ml
  16. 2 2
      src/typing/typeloadFields.ml
  17. 1 0
      src/typing/typeloadParse.ml
  18. 2 2
      std/Std.hx
  19. 1 1
      std/StringTools.hx
  20. 1 1
      std/Sys.hx
  21. 4 4
      std/Type.hx
  22. 3 3
      std/Xml.hx
  23. 2 2
      std/cpp/_std/Std.hx
  24. 1 1
      std/cpp/_std/Sys.hx
  25. 4 4
      std/cpp/_std/Type.hx
  26. 11 0
      std/cpp/vm/Debugger.hx
  27. 1 1
      std/eval/_std/Sys.hx
  28. 2 2
      std/flash/_std/Std.hx
  29. 4 4
      std/flash/_std/Type.hx
  30. 1 1
      std/flash/_std/haxe/Http.hx
  31. 2 2
      std/haxe/Resource.hx
  32. 2 1
      std/haxe/Serializer.hx
  33. 1 1
      std/haxe/Template.hx
  34. 8 8
      std/haxe/Unserializer.hx
  35. 1 1
      std/haxe/format/JsonPrinter.hx
  36. 1 1
      std/haxe/http/HttpBase.hx
  37. 1 1
      std/haxe/http/HttpJs.hx
  38. 1 1
      std/haxe/http/HttpNodeJs.hx
  39. 1 1
      std/haxe/io/BufferInput.hx
  40. 1 1
      std/haxe/macro/Printer.hx
  41. 1 1
      std/haxe/xml/Printer.hx
  42. 8 12
      std/haxe/zip/Huffman.hx
  43. 10 13
      std/haxe/zip/InflateImpl.hx
  44. 54 51
      std/haxe/zip/Reader.hx
  45. 11 1
      std/hl/CArray.hx
  46. 2 2
      std/hl/_std/Std.hx
  47. 1 1
      std/hl/_std/Sys.hx
  48. 4 4
      std/hl/_std/Type.hx
  49. 2 2
      std/js/_std/Std.hx
  50. 6 6
      std/js/_std/Type.hx
  51. 2 2
      std/jvm/_std/Std.hx
  52. 1 1
      std/jvm/_std/Sys.hx
  53. 4 4
      std/jvm/_std/Type.hx
  54. 2 2
      std/lua/_std/Std.hx
  55. 1 1
      std/lua/_std/Sys.hx
  56. 4 4
      std/lua/_std/Type.hx
  57. 2 2
      std/neko/_std/Std.hx
  58. 1 1
      std/neko/_std/Sys.hx
  59. 4 4
      std/neko/_std/Type.hx
  60. 2 2
      std/php/_std/Std.hx
  61. 1 1
      std/php/_std/StringTools.hx
  62. 1 1
      std/php/_std/Sys.hx
  63. 4 4
      std/php/_std/Type.hx
  64. 1 1
      std/python/Boot.hx
  65. 2 2
      std/python/_std/Std.hx
  66. 1 1
      std/python/_std/Sys.hx
  67. 4 4
      std/python/_std/Type.hx
  68. 1 1
      std/sys/Http.hx
  69. 1 1
      tests/misc/projects/Issue10147/Main.hx
  70. 1 0
      tests/misc/projects/Issue10147/compile-fail.hxml.stderr
  71. 14 0
      tests/misc/projects/Issue10782/ArrayAccess.hx
  72. 22 0
      tests/misc/projects/Issue10782/Main.hx
  73. 7 0
      tests/misc/projects/Issue10782/NoPostfix.hx
  74. 1 0
      tests/misc/projects/Issue10782/compile-array-access.hxml
  75. 1 0
      tests/misc/projects/Issue10782/compile-array-access.hxml.stdout
  76. 1 0
      tests/misc/projects/Issue10782/compile-no-postfix.hxml
  77. 1 0
      tests/misc/projects/Issue10782/compile.hxml
  78. 5 0
      tests/misc/projects/Issue11164/Macro.hx
  79. 29 0
      tests/misc/projects/Issue11164/Main.hx
  80. 5 0
      tests/misc/projects/Issue11164/Main2.hx
  81. 3 0
      tests/misc/projects/Issue11164/Main3.hx
  82. 3 0
      tests/misc/projects/Issue11164/Main4.hx
  83. 3 0
      tests/misc/projects/Issue11164/Main5.hx
  84. 2 0
      tests/misc/projects/Issue11164/Main6.hx
  85. 5 0
      tests/misc/projects/Issue11164/Main7.hx
  86. 3 0
      tests/misc/projects/Issue11164/compile.hxml
  87. 36 0
      tests/misc/projects/Issue11164/compile.hxml.stderr
  88. 3 0
      tests/misc/projects/Issue11164/compile2-fail.hxml
  89. 6 0
      tests/misc/projects/Issue11164/compile2-fail.hxml.stderr
  90. 3 0
      tests/misc/projects/Issue11164/compile3-fail.hxml
  91. 6 0
      tests/misc/projects/Issue11164/compile3-fail.hxml.stderr
  92. 3 0
      tests/misc/projects/Issue11164/compile4-fail.hxml
  93. 6 0
      tests/misc/projects/Issue11164/compile4-fail.hxml.stderr
  94. 3 0
      tests/misc/projects/Issue11164/compile5-fail.hxml
  95. 6 0
      tests/misc/projects/Issue11164/compile5-fail.hxml.stderr
  96. 3 0
      tests/misc/projects/Issue11164/compile6-fail.hxml
  97. 6 0
      tests/misc/projects/Issue11164/compile6-fail.hxml.stderr
  98. 3 0
      tests/misc/projects/Issue11164/compile7-fail.hxml
  99. 6 0
      tests/misc/projects/Issue11164/compile7-fail.hxml.stderr
  100. 2 0
      tests/misc/projects/Issue11389/Main.hx

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

@@ -734,6 +734,11 @@ jobs:
           mkdir "$env:HAXELIB_ROOT"
           haxelib setup "$env:HAXELIB_ROOT"
 
+      - name: Add msbuild to PATH (hl/c)
+        uses: microsoft/setup-msbuild@v2
+        with:
+          msbuild-architecture: x64
+
       - name: Test
         shell: pwsh
         run: haxe RunCi.hxml

+ 1 - 0
extra/github-actions/test-mac.yml

@@ -30,3 +30,4 @@
     echo "" > sys/compile-fs.hxml
     haxe RunCi.hxml
   working-directory: ${{github.workspace}}/tests
+  timeout-minutes: 60

+ 6 - 0
extra/github-actions/test-windows.yml

@@ -53,7 +53,13 @@
     mkdir "$env:HAXELIB_ROOT"
     haxelib setup "$env:HAXELIB_ROOT"
 
+- name: Add msbuild to PATH (hl/c)
+  uses: microsoft/setup-msbuild@v2
+  with:
+    msbuild-architecture: x64
+
 - name: Test
   shell: pwsh
   run: haxe RunCi.hxml
   working-directory: ${{github.workspace}}/tests
+  timeout-minutes: 20

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

@@ -179,6 +179,7 @@ jobs:
       - name: Test
         run: haxe RunCi.hxml
         working-directory: ${{github.workspace}}/tests
+        timeout-minutes: 20
 
   test-docgen:
     needs: linux-build
@@ -361,6 +362,7 @@ jobs:
       - name: Test
         run: haxe RunCi.hxml
         working-directory: ${{github.workspace}}/tests
+        timeout-minutes: 20
 
   mac-build:
     strategy:

+ 1 - 1
src/compiler/compiler.ml

@@ -134,7 +134,7 @@ module Setup = struct
 				add_std "php";
 				"php"
 			| Cpp ->
-				Common.define_value com Define.HxcppApiLevel "430";
+				Common.define_value com Define.HxcppApiLevel "500";
 				add_std "cpp";
 				if Common.defined com Define.Cppia then
 					actx.classes <- (Path.parse_path "cpp.cppia.HostClasses" ) :: actx.classes;

+ 1 - 1
src/core/ast.ml

@@ -466,7 +466,7 @@ let gen_doc_text_opt = Option.map gen_doc_text
 
 let get_own_doc_opt = Option.map_default (fun d -> d.doc_own) None
 
-let is_postfix (e,_) op = match op with
+let is_postfix op = match op with
 	| Increment | Decrement | Not -> true
 	| Neg | NegBits | Spread -> false
 

+ 64 - 51
src/filters/filters.ml

@@ -178,30 +178,39 @@ let iter_expressions fl mt =
 
 open FilterContext
 
-let destruction_before_dce scom types =
+let destruction_before_dce pool scom all_types_array =
 	let filters = [
-		(fun _ -> FiltersCommon.remove_generic_base);
-		(fun _ -> apply_macro_exclude);
-		(fun _ -> remove_extern_fields scom);
+		FiltersCommon.remove_generic_base;
+		apply_macro_exclude;
+		remove_extern_fields scom;
 		(* check @:remove metadata before DCE so it is ignored there (issue #2923) *)
-		(fun _ -> check_remove_metadata);
+		check_remove_metadata;
 	] in
-	SafeCom.run_type_filters_safe scom filters types
+	Parallel.ParallelArray.iter pool (fun mt -> List.iter (fun f -> f mt) filters) all_types_array
 
-let destruction_on_scom scom ectx rename_locals_config types =
-	let filters = [
+let destruction_on_scom pool scom ectx rename_locals_config all_types_array =
+	let filters1 = [
 		SaveStacks.patch_constructors ectx;
 		(fun _ -> Native.apply_native_paths);
-		(fun _ -> add_rtti scom);
+	] in
+	let filters2 = [
 		(match scom.platform with | Jvm -> (fun _ _ -> ()) | _ -> (fun scom mt -> AddFieldInits.add_field_inits scom.curclass.cl_path rename_locals_config scom mt));
 		(fun _ -> check_void_field);
-		(fun _ -> (match scom.platform with | Cpp -> promote_first_interface_to_super | _ -> (fun _ -> ())));
+		(fun _ -> (match scom.platform with | Cpp -> promote_first_interface_to_super | _ -> (fun _ -> ()))); (* accesses cl_super, cl_implements  *)
 		(fun _ -> (if scom.platform_config.pf_reserved_type_paths <> [] then check_reserved_type_paths scom else (fun _ -> ())));
 	] in
-	SafeCom.run_type_filters_safe scom filters types
+	Parallel.ParallelArray.iter pool (fun mt ->
+		let scom = adapt_scom_to_mt scom mt in
+		List.iter (fun f -> f scom mt) filters1
+	) all_types_array;
+	Parallel.ParallelArray.iter pool (fun mt ->
+		let scom = adapt_scom_to_mt scom mt in
+		List.iter (fun f -> f scom mt) filters2
+	) all_types_array
 
 let destruction_on_com scom com types =
 	let filters = [
+		(fun _ -> add_rtti scom); (* accesses cl_super *)
 		(fun _ -> check_private_path com);
 		(match com.platform with Hl -> (fun _ _ -> ()) | _ -> (fun _ -> add_meta_field com));
 		(fun _ -> commit_features com);
@@ -209,50 +218,53 @@ let destruction_on_com scom com types =
 	(* These aren't actually safe. The logic works fine regardless, we just can't parallelize this at the moment. *)
 	SafeCom.run_type_filters_safe scom filters types
 
-let destruction (com : Common.context) scom ectx detail_times main rename_locals_config types =
-	with_timer scom.timer_ctx detail_times "type 2" None (fun () ->
-		SafeCom.run_with_scom com scom (fun () ->
-			destruction_before_dce scom types
-		)
-	);
+let destruction (com : Common.context) scom ectx detail_times main rename_locals_config all_types all_types_array =
+	let all_types = Parallel.run_in_new_pool scom.timer_ctx (fun pool ->
+		with_timer scom.timer_ctx detail_times "type 2" None (fun () ->
+			SafeCom.run_with_scom com scom (fun () ->
+				destruction_before_dce pool scom all_types_array
+			)
+		);
 
-	Common.enter_stage com CDceStart;
-	with_timer scom.timer_ctx detail_times "dce" None (fun () ->
-		(* DCE *)
-		let dce_mode = try Define.defined_value scom.defines Define.Dce with _ -> "no" in
-		let dce_mode = match dce_mode with
-			| "full" -> if Define.defined scom.defines Define.Interp then Dce.DceNo else DceFull
-			| "std" -> DceStd
-			| "no" -> DceNo
-			| _ -> failwith ("Unknown DCE mode " ^ dce_mode)
-		in
-		let std_paths = com.class_paths#get_std_paths in
-		let mscom = Option.map of_com (com.get_macros()) in
-		let types = Dce.run scom mscom main dce_mode std_paths types in
-		com.types <- types
-	);
-	Common.enter_stage com CDceDone;
-	let types = com.types in
-
-	(* This has to run after DCE, or otherwise its condition always holds. *)
-	begin match ectx with
-		| Some ectx when Common.has_feature com "haxe.NativeStackTrace.exceptionStack" ->
-			List.iter (
-				SafeCom.run_expression_filters_safe ~ignore_processed_status:true scom detail_times ["insert_save_stacks",SaveStacks.insert_save_stacks ectx]
-			) types
-		| _ ->
-			()
-	end;
+		Common.enter_stage com CDceStart;
+		let all_types = with_timer scom.timer_ctx detail_times "dce" None (fun () ->
+			(* DCE *)
+			let dce_mode = try Define.defined_value scom.defines Define.Dce with _ -> "no" in
+			let dce_mode = match dce_mode with
+				| "full" -> if Define.defined scom.defines Define.Interp then Dce.DceNo else DceFull
+				| "std" -> DceStd
+				| "no" -> DceNo
+				| _ -> failwith ("Unknown DCE mode " ^ dce_mode)
+			in
+			let std_paths = com.class_paths#get_std_paths in
+			let mscom = Option.map of_com (com.get_macros()) in
+			let types = Dce.run pool scom mscom main dce_mode std_paths all_types in
+			types
+		) in
+		Common.enter_stage com CDceDone;
+
+		(* This has to run after DCE, or otherwise its condition always holds. *)
+		begin match ectx with
+			| Some ectx when Common.has_feature com "haxe.NativeStackTrace.exceptionStack" ->
+				Parallel.ParallelArray.iter pool (
+					SafeCom.run_expression_filters_safe ~ignore_processed_status:true scom detail_times ["insert_save_stacks",SaveStacks.insert_save_stacks ectx]
+				)  all_types_array
+			| _ ->
+				()
+		end;
 
-	with_timer scom.timer_ctx detail_times "type 3" None (fun () ->
-		SafeCom.run_with_scom com scom (fun () ->
-			destruction_on_scom scom ectx rename_locals_config types
-		)
-	);
+		with_timer scom.timer_ctx detail_times "type 3" None (fun () ->
+			SafeCom.run_with_scom com scom (fun () ->
+				destruction_on_scom pool scom ectx rename_locals_config all_types_array
+			)
+		);
+		all_types
+	) in
+	com.types <- all_types;
 
 	with_timer scom.timer_ctx detail_times "type 4" None (fun () ->
 		SafeCom.run_with_scom com scom (fun () ->
-			destruction_on_com scom com types
+			destruction_on_com scom com all_types
 		)
 	);
 
@@ -510,4 +522,5 @@ let run com ectx main before_destruction =
 		com.callbacks#run com.error_ext com.callbacks#get_after_save;
 	);
 	before_destruction();
-	destruction com scom ectx detail_times main rename_locals_config com.types
+	let all_types_array = Array.of_list com.types in
+	destruction com scom ectx detail_times main rename_locals_config com.types all_types_array

+ 1 - 1
src/generators/cpp/gen/cppCppia.ml

@@ -786,7 +786,7 @@ class script_writer ctx filename asciiOut =
     method wpos p =
       if debug then
         this#write
-          (this#fileText p.pfile ^ "\t"
+          (this#fileText (Path.get_full_path p.pfile) ^ "\t"
           ^ string_of_int (Lexer.get_error_line p)
           ^ indent)
 

+ 18 - 11
src/generators/genhl.ml

@@ -769,7 +769,7 @@ and enum_class ctx e =
 			p.pindex <- PMap.add name (fid, t) p.pindex;
 			fid
 		in
-			PMap.iter (fun _ ef -> 
+			PMap.iter (fun _ ef ->
 			(match follow ef.ef_type with
 				| TEnum _ -> ignore(add_field ef.ef_name (to_type ctx ef.ef_type))
 				| TFun (args, ret) ->
@@ -2609,14 +2609,14 @@ and eval_expr ctx e =
 				free ctx ra;
 				free ctx ridx;
 				v
-            | ACArray (ra, _, ridx) ->
+			| ACArray (ra, t, ridx) ->
 				hold ctx ra;
 				hold ctx ridx;
-                let v = value() in
-                op ctx (OSetArray (ra,ridx,v));
-                free ctx ridx;
-                free ctx ra;
-                v
+				let v = eval_to ctx e2 t in
+				op ctx (OSetArray (ra,ridx,v));
+				free ctx ridx;
+				free ctx ra;
+				v
 			| ADynamic (ethis,f) ->
 				let obj = eval_null_check ctx ethis in
 				hold ctx obj;
@@ -3565,13 +3565,20 @@ let generate_member ctx c f =
 		in
 		ignore(make_fun ?gen_content ctx (s_type_path c.cl_path,f.cf_name) (alloc_fid ctx c f) ff (Some c) None);
 		if f.cf_name = "toString" && not (has_class_field_flag f CfOverride) && not (PMap.mem "__string" c.cl_fields) && is_to_string f.cf_type then begin
-			let p = f.cf_pos in
-			(* function __string() return this.toString().bytes *)
+			let p = {f.cf_pos with pmax = f.cf_pos.pmin} in
+			(* function __string() { var str = this.toString(); return if (str == null) null else str.bytes; } *)
 			let ethis = mk (TConst TThis) (TInst (c,extract_param_types c.cl_params)) p in
 			let tstr = mk (TCall (mk (TField (ethis,FInstance(c,extract_param_types c.cl_params,f))) f.cf_type p,[])) ctx.com.basic.tstring p in
+			let vtmp = Type.alloc_var VGenerated "str" ctx.com.basic.tstring p in
+			let vstr = mk (TLocal vtmp) ctx.com.basic.tstring p in
 			let cstr, cf_bytes = (try (match ctx.com.basic.tstring with TInst(c,_) -> c, PMap.find "bytes" c.cl_fields | _ -> die "" __LOC__) with Not_found -> die "" __LOC__) in
-			let estr = mk (TReturn (Some (mk (TField (tstr,FInstance (cstr,[],cf_bytes))) cf_bytes.cf_type p))) ctx.com.basic.tvoid p in
-			ignore(make_fun ctx (s_type_path c.cl_path,"__string") (alloc_fun_path ctx c.cl_path "__string") { tf_expr = estr; tf_args = []; tf_type = cf_bytes.cf_type; } (Some c) None)
+			let ebytes = mk (TField (vstr,FInstance (cstr,[],cf_bytes))) cf_bytes.cf_type p in
+			let econd = mk (TBinop (OpEq, vstr, mk (TConst TNull) ctx.com.basic.tstring p)) ctx.com.basic.tbool p in
+			let efun = mk (TBlock [
+				mk (TVar (vtmp,Some tstr)) ctx.com.basic.tvoid p;
+				mk (TReturn (Some (mk (TIf (econd, mk (TConst TNull) cf_bytes.cf_type p, Some ebytes)) cf_bytes.cf_type p))) cf_bytes.cf_type p
+			]) ctx.com.basic.tvoid p in
+			ignore(make_fun ctx (s_type_path c.cl_path,"__string") (alloc_fun_path ctx c.cl_path "__string") { tf_expr = efun; tf_args = []; tf_type = cf_bytes.cf_type; } (Some c) None)
 		end
 
 let generate_type ctx t =

+ 12 - 11
src/generators/hl2c.ml

@@ -875,14 +875,15 @@ let generate_function gctx ctx f =
 		| OUMod (r,a,b) ->
 			sexpr "%s = %s == 0 ? 0 : ((unsigned)%s) %% ((unsigned)%s)" (reg r) (reg b) (reg a) (reg b)
 		| OShl (r,a,b) ->
-			sexpr "%s = %s << %s" (reg r) (reg a) (reg b)
+			let size = (match rtype r with HUI8 -> 8 | HUI16 -> 16 | HI32 -> 32 | HI64 -> 64 |_ -> Globals.die "" __LOC__ ) in
+			sexpr "%s = %s << (%s %% %d)" (reg r) (reg a) (reg b) size
 		| OSShr (r,a,b) ->
-			sexpr "%s = %s >> %s" (reg r) (reg a) (reg b)
+			let size = (match rtype r with HUI8 -> 8 | HUI16 -> 16 | HI32 -> 32 | HI64 -> 64 |_ -> Globals.die "" __LOC__ ) in
+			sexpr "%s = %s >> (%s %% %d)" (reg r) (reg a) (reg b) size
 		| OUShr (r,a,b) ->
-			(match rtype r with
-			| HI64 -> sexpr "%s = ((uint64)%s) >> %s" (reg r) (reg a) (reg b)
-			| _ -> sexpr "%s = ((unsigned)%s) >> %s" (reg r) (reg a) (reg b)
-			);
+			let size = (match rtype r with HUI8 -> 8 | HUI16 -> 16 | HI32 -> 32 | HI64 -> 64 |_ -> Globals.die "" __LOC__ ) in
+			let prefix = (match rtype r with HI64 -> "uint64" | _ -> "unsigned") in
+			sexpr "%s = ((%s)%s) >> (%s %% %d)" (reg r) prefix (reg a) (reg b) size
 		| OAnd (r,a,b) ->
 			sexpr "%s = %s & %s" (reg r) (reg a) (reg b)
 		| OOr (r,a,b) ->
@@ -1042,11 +1043,11 @@ let generate_function gctx ctx f =
 		| OSetMem (b,idx,r) ->
 			sexpr "*(%s*)(%s + %s) = %s" (ctype (rtype r)) (reg b) (reg idx) (reg r)
 		| OSetArray (arr,idx,v) ->
-            (match rtype arr with
-            | HAbstract _ ->
-			    sexpr "((%s*)%s)[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v)
-            | _ ->
-			    sexpr "((%s*)(%s + 1))[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v))
+			(match rtype arr with
+			| HAbstract _ ->
+				sexpr "((%s)%s)[%s] = *%s" (ctype (rtype v)) (reg arr) (reg idx) (reg v)
+			| _ ->
+				sexpr "((%s*)(%s + 1))[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v))
 		| OSafeCast (r,v) ->
 			let tsrc = rtype v in
 			let t = rtype r in

+ 6 - 6
src/optimization/dce.ml

@@ -827,8 +827,8 @@ let collect_entry_points dce types =
 		) dce.added_fields;
 	end
 
-let mark dce =
-	let rec loop pool =
+let mark pool dce =
+	let rec loop () =
 		if DynArray.length dce.added_fields > 0 then begin
 			let cfl = DynArray.to_array dce.added_fields in
 			DynArray.clear dce.added_fields;
@@ -847,10 +847,10 @@ let mark dce =
 					List.iter (fun cf -> if cf.cf_expr <> None then opt (expr dce) cf.cf_expr) cf.cf_overloads;
 				end
 			) cfl;
-			loop pool
+			loop ()
 		end
 	in
-	Parallel.run_in_new_pool dce.scom.timer_ctx loop
+	loop ()
 
 let sweep dce types =
 	let rec loop acc types =
@@ -929,7 +929,7 @@ let sweep dce types =
 	in
 	loop [] (List.rev types)
 
-let run scom mscom main mode std_paths types =
+let run pool scom mscom main mode std_paths types =
 	let full = mode = DceFull in
 	let dce = {
 		scom = scom;
@@ -954,7 +954,7 @@ let run scom mscom main mode std_paths types =
 	Timer.time scom.timer_ctx ["filters";"dce";"collect"] collect_entry_points dce types;
 
 	(* second step: initiate DCE passes and keep going until no new fields were added *)
-	Timer.time scom.timer_ctx ["filters";"dce";"mark"] mark dce;
+	Timer.time scom.timer_ctx ["filters";"dce";"mark"] (mark pool) dce;
 
 	(* third step: filter types *)
 	let types = if mode <> DceNo then

+ 20 - 3
src/syntax/grammar.ml

@@ -333,7 +333,13 @@ and parse_type_decl ctx mode s =
 					}, punion p1 p2)
 				| [ ] -> check_type_decl_flag_completion ctx mode c s)
 			| _ ->
-				check_type_decl_flag_completion ctx mode c s
+				begin match meta with
+					| (_,_,p) :: _ ->
+						syntax_error ctx ~pos:(Some p) (Custom "Type or field expected after metadata") s ()
+					| [] ->
+						()
+				end;
+				check_type_decl_flag_completion ctx mode c s;
 
 
 and parse_class ctx doc meta cflags need_name s =
@@ -709,6 +715,8 @@ and parse_complex_type_inner ctx allow_named s = match%parser s with
 		in
 		let p = punion p1 p2 in
 		CTPath (make_ptp (mk_type_path ~params:[TPType hint] (["haxe"],"Rest")) p),p
+	| [ (Kwd Default,p) ] ->
+		CTPath (make_ptp (mk_type_path (["$"],"_hx_default")) p),p
 	| [ dollar_ident as n ] ->
 		(match%parser s with
 		| [ (DblDot,_); [%let t = parse_complex_type ctx] ] when allow_named->
@@ -1164,6 +1172,7 @@ and parse_block_var ctx = function%parser
 and parse_block_elt ctx s = match%parser s with
 	| [ [%let vl,p = parse_block_var ctx] ] ->
 		(EVars vl,p)
+	| [ (Kwd Function,p1); [%let e = parse_function ctx p1 false]; [%let _s = semicolon ctx] ]  -> e
 	| [ (Kwd Inline,p1) ] ->
 		begin match%parser s with
 		| [ (Kwd Function,_); [%let e = parse_function ctx p1 true]; [%let _s = semicolon ctx] ] -> e
@@ -1486,7 +1495,15 @@ and expr (ctx : parser_ctx) s = match%parser s with
 				syntax_error ctx (Expected [")";",";":"]) s (expr_next ctx (EParenthesis e, punion p1 (pos e)) s))
 		)
 	| [ (BkOpen,p1); [%let e = parse_array_decl ctx p1] ] -> expr_next ctx e s
-	| [ (Kwd Function,p1); [%let e = parse_function ctx p1 false]; ] -> e
+	| [ (Kwd Function,p1); [%let e = parse_function ctx p1 false]; [%s s]; ] ->
+		begin match Stream.peek s with
+		| Some (POpen,_) | Some (BkOpen,_) ->
+			e
+		| Some (Unop op, _) when is_postfix op ->
+			e
+		| _ ->
+			expr_next ctx e s
+		end
 	| [ (Unop op,p1); [%let e = expr ctx] ] -> make_unop op e p1
 	| [ (Spread,p1); [%let e = expr ctx] ] -> make_unop Spread e (punion p1 (pos e))
 	| [ (Binop OpSub,p1); [%let e = expr ctx] ] ->
@@ -1610,7 +1627,7 @@ and expr_next' ctx e1 s = match%parser s with
 			make_binop OpGt e1 e2)
 	| [ (Binop op,_); [%let e2 = secure_expr ctx] ] -> make_binop op e1 e2
 	| [ (Spread,_); [%let e2 = secure_expr ctx] ] -> make_binop OpInterval e1 e2
-	| [ (Unop op,p) ] when is_postfix e1 op ->
+	| [ (Unop op,p) ] when is_postfix op ->
 		expr_next ctx (EUnop (op,Postfix,e1), punion (pos e1) p) s
 	| [ (Question,_); [%let e2 = expr ctx] ] ->
 		begin match%parser s with

+ 4 - 1
src/typing/macroContext.ml

@@ -819,10 +819,13 @@ let load_macro' ctx display cpath f p =
 	fst (load_macro'' ctx.com (get_macro_context ctx) display cpath f p)
 
 let do_call_macro com api cpath name args p =
+	if com.verbose then Common.log com ("Calling macro " ^ s_type_path cpath ^ "." ^ name ^ " (" ^ p.pfile ^ ":" ^ string_of_int (Lexer.get_error_line p) ^ ")");
 	incr stats.s_macros_called;
 	let timer_level = Timer.level_from_define com.defines Define.MacroTimes in
 	let f = Interp.call_path (Interp.get_ctx()) ((fst cpath) @ [snd cpath]) name args in
-	macro_timer com.timer_ctx timer_level "execution" (Some (s_type_path cpath ^ "." ^ name)) f api
+	let r = macro_timer com.timer_ctx timer_level "execution" (Some (s_type_path cpath ^ "." ^ name)) f api in
+	if com.verbose then Common.log com ("Exiting macro " ^ s_type_path cpath ^ "." ^ name);
+	r
 
 let load_macro ctx com mctx api display cpath f p =
 	let meth,mloaded = load_macro'' com mctx display cpath f p in

+ 32 - 16
src/typing/nullSafety.ml

@@ -1076,8 +1076,26 @@ class expr_checker mode immediate_execution report =
 			E.g.: `Array<Null<String>>` vs `Array<String>` returns `true`, but also adds a compilation error.
 		*)
 		method can_pass_expr expr to_type p =
+			let try_unify expr to_type =
+				if self#is_nullable_expr expr && not (is_nullable_type ~dynamic_is_nullable:true to_type) then
+					false
+				else begin
+					let expr_type = unfold_null expr.etype in
+					try
+						new unificator#unify expr_type to_type;
+						true
+					with
+						| Safety_error err ->
+							self#error ("Cannot unify " ^ (str_type expr_type) ^ " with " ^ (str_type to_type)) [p; expr.epos];
+							(* returning `true` because error is already logged in the line above *)
+							true
+						| e ->
+							fail ~msg:"Null safety unification failure" expr.epos __POS__
+				end
+			in
 			match expr.eexpr, to_type with
 				| TLocal v, _ when contains_unsafe_meta v.v_meta -> true
+				| TObjectDecl fields, TAbstract ({ a_path = ([],"Null") }, [TAnon to_type])
 				| TObjectDecl fields, TAnon to_type ->
 					List.for_all
 						(fun ((name, _, _), field_expr) ->
@@ -1086,22 +1104,20 @@ class expr_checker mode immediate_execution report =
 								self#can_pass_expr field_expr field_to_type.cf_type p
 							with Not_found -> false)
 						fields
-				| _, _ ->
-					if self#is_nullable_expr expr && not (is_nullable_type ~dynamic_is_nullable:true to_type) then
-						false
-					else begin
-						let expr_type = unfold_null expr.etype in
-						try
-							new unificator#unify expr_type to_type;
-							true
-						with
-							| Safety_error err ->
-								self#error ("Cannot unify " ^ (str_type expr_type) ^ " with " ^ (str_type to_type)) [p; expr.epos];
-								(* returning `true` because error is already logged in the line above *)
-								true
-							| e ->
-								fail ~msg:"Null safety unification failure" expr.epos __POS__
-					end
+				| TObjectDecl fields, TAbstract ({ a_path = ([],"Null") }, [TType (t,tl)])
+				| TObjectDecl fields, TType (t,tl) ->
+					(match follow_without_null t.t_type with
+							| TAnon to_type ->
+								List.for_all
+									(fun ((name, _, _), field_expr) ->
+										try
+											let field_to_type = PMap.find name to_type.a_fields in
+											self#can_pass_expr field_expr field_to_type.cf_type p
+										with Not_found -> false)
+									fields
+							| _ -> try_unify expr to_type
+					)
+				| _, _ -> try_unify expr to_type
 		(**
 			Should be called for the root expressions of a method or for then initialization expressions of fields.
 		*)

+ 14 - 3
src/typing/typeload.ml

@@ -299,7 +299,7 @@ let rec load_params ctx info params p =
 	let is_rest = info.build_kind = BuildGenericBuild && (match info.build_params with [{ttp_name="Rest"}] -> true | _ -> false) in
 	let is_java_rest = ctx.com.platform = Jvm && info.build_extern in
 	let is_rest = is_rest || is_java_rest in
-	let load_param t =
+	let load_param t ttp =
 		match t with
 		| TPExpr e ->
 			let name = (match fst e with
@@ -314,6 +314,16 @@ let rec load_params ctx info params p =
 			let c = mk_class ctx.m.curmod ([],name) p (pos e) in
 			c.cl_kind <- KExpr e;
 			TInst (c,[]),pos e
+		| TPType (CTPath({ path = { tpackage = ["$"]; tname = "_hx_default" }}),p) ->
+			(match ttp with
+				| Some { ttp_default = Some def } -> def,p
+				| Some ttp ->
+					raise_typing_error (Printf.sprintf "Invalid default, type parameter %s has no default value" ttp.ttp_name) p
+				| None when is_rest ->
+					raise_typing_error "Cannot use default with rest type parameters" p
+				| None ->
+					raise_typing_error ("Too many type parameters for " ^ s_type_path info.build_path) p
+			)
 		| TPType t ->
 			load_complex_type ctx true LoadNormal t,pos t
 	in
@@ -321,7 +331,7 @@ let rec load_params ctx info params p =
 	let rec loop tl1 tl2 is_rest = match tl1,tl2 with
 		| t :: tl1,ttp:: tl2 ->
 			let name = ttp.ttp_name in
-			let t,pt = load_param t in
+			let t,pt = load_param t (Some ttp) in
 			let check_const c =
 				let is_expression = (match t with TInst ({ cl_kind = KExpr _ },_) -> true | _ -> false) in
 				let expects_expression = name = "Const" || Meta.has Meta.Const c.cl_meta in
@@ -360,7 +370,7 @@ let rec load_params ctx info params p =
 					t :: loop [] tl is_rest
 			end
 		| t :: tl,[] ->
-			let t,pt = load_param t in
+			let t,pt = load_param t None in
 			if is_rest then
 				t :: loop tl [] true
 			else if ignore_error ctx.com then
@@ -439,6 +449,7 @@ and load_complex_type' ctx allow_display mode (t,p) =
 	match t with
 	| CTParent t -> load_complex_type ctx allow_display mode t
 	| CTPath { path = {tpackage = ["$"]; tname = "_hx_mono" }} -> spawn_monomorph ctx p
+	| CTPath { path = {tpackage = ["$"]; tname = "_hx_default" }} -> raise_typing_error "Invalid type : default" p
 	| CTPath ptp -> load_instance ~allow_display ctx ptp ParamNormal mode
 	| CTOptional _ -> raise_typing_error "Optional type not allowed here" p
 	| CTNamed _ -> raise_typing_error "Named type not allowed here" p

+ 2 - 2
src/typing/typeloadFields.ml

@@ -754,7 +754,7 @@ module TypeBinding = struct
 			(* type constant init fields (issue #1956) *)
 			if not ctx.g.return_partial_type || (match fst e with EConst _ -> true | _ -> false) then begin
 				enter_field_typing_pass ctx.g ("bind_var_expression",fst ctx.c.curclass.cl_path @ [snd ctx.c.curclass.cl_path;ctx.f.curfield.cf_name]);
-				if (Meta.has (Meta.Custom ":debug.typing") (c.cl_meta @ cf.cf_meta)) then ctx.com.print (Printf.sprintf "Typing field %s.%s\n" (s_type_path c.cl_path) cf.cf_name);
+				if ctx.com.verbose then Common.log ctx.com ("Typing " ^ (if ctx.com.is_macro_context then "macro " else "") ^ s_type_path c.cl_path ^ "." ^ cf.cf_name);
 				let e = type_var_field ctx t e fctx.is_static fctx.is_display_field p in
 				let maybe_run_analyzer e = match e.eexpr with
 					| TConst _ | TLocal _ | TFunction _ -> e
@@ -831,7 +831,7 @@ module TypeBinding = struct
 		let ctx = TyperManager.clone_for_expr ctx_f fmode true in
 		let bind () =
 			incr stats.s_methods_typed;
-			if (Meta.has (Meta.Custom ":debug.typing") (c.cl_meta @ cf.cf_meta)) then ctx.com.print (Printf.sprintf "Typing method %s.%s\n" (s_type_path c.cl_path) cf.cf_name);
+			if ctx.com.verbose then Common.log ctx.com ("Typing " ^ (if ctx.com.is_macro_context then "macro " else "") ^ s_type_path c.cl_path ^ "." ^ cf.cf_name);
 			begin match ctx.com.platform with
 				| Jvm when is_java_native_function ctx cf.cf_meta cf.cf_pos ->
 					if e <> None then

+ 1 - 0
src/typing/typeloadParse.ml

@@ -52,6 +52,7 @@ let parse_file_from_lexbuf com file p lexbuf =
 		| _ ->
 			()
 	end;
+	Common.log com ("Parsed " ^ file);
 	parse_result
 
 let parse_file_from_lexbuf com file p lexbuf =

+ 2 - 2
std/Std.hx

@@ -60,10 +60,10 @@ extern class Std {
 		If `value` is null, the result is null. If `c` is null, the result is
 		unspecified.
 	**/
-	static function downcast<T:{}, S:T>(value:T, c:Class<S>):S;
+	static function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S>;
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	static function instance<T:{}, S:T>(value:T, c:Class<S>):S;
+	static function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S>;
 
 	/**
 		Converts any value to a String.

+ 1 - 1
std/StringTools.hx

@@ -151,7 +151,7 @@ class StringTools {
 		- `"` becomes `&quot`;
 		- `'` becomes `&#039`;
 	**/
-	public static function htmlEscape(s:String, ?quotes:Bool):String {
+	public static function htmlEscape(s:String, quotes = false):String {
 		var buf = new StringBuf();
 		for (code in #if neko iterator(s) #else new haxe.iterators.StringIteratorUnicode(s) #end) {
 			switch (code) {

+ 1 - 1
std/Sys.hx

@@ -50,7 +50,7 @@ extern class Sys {
 		Returns the value of the given environment variable, or `null` if it
 		doesn't exist.
 	**/
-	static function getEnv(s:String):String;
+	static function getEnv(s:String):Null<String>;
 
 	/**
 		Sets the value of the given environment variable.

+ 4 - 4
std/Type.hx

@@ -49,7 +49,7 @@ extern class Type {
 
 		In general, type parameter information cannot be obtained at runtime.
 	**/
-	static function getEnum(o:EnumValue):Enum<Dynamic>;
+	static function getEnum(o:EnumValue):Null<Enum<Dynamic>>;
 
 	/**
 		Returns the super-class of class `c`.
@@ -60,7 +60,7 @@ extern class Type {
 
 		In general, type parameter information cannot be obtained at runtime.
 	**/
-	static function getSuperClass(c:Class<Dynamic>):Class<Dynamic>;
+	static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>>;
 
 	/**
 		Returns the name of class `c`, including its path.
@@ -108,7 +108,7 @@ extern class Type {
 
 		The class name must not include any type parameters.
 	**/
-	static function resolveClass(name:String):Class<Dynamic>;
+	static function resolveClass(name:String):Null<Class<Dynamic>>;
 
 	/**
 		Resolves an enum by name.
@@ -123,7 +123,7 @@ extern class Type {
 
 		The enum name must not include any type parameters.
 	**/
-	static function resolveEnum(name:String):Enum<Dynamic>;
+	static function resolveEnum(name:String):Null<Enum<Dynamic>>;
 
 	/**
 		Creates an instance of class `cl`, using `args` as arguments to the

+ 3 - 3
std/Xml.hx

@@ -143,7 +143,7 @@ class Xml {
 		Returns the parent object in the Xml hierarchy.
 		The parent can be `null`, an Element or a Document.
 	**/
-	public var parent(default, null):Xml;
+	public var parent(default, null):Null<Xml>;
 
 	var children:Array<Xml>;
 	var attributeMap:Map<String, String>;
@@ -241,7 +241,7 @@ class Xml {
 		Get the given attribute of an Element node. Returns `null` if not found.
 		Attributes are case-sensitive.
 	**/
-	public function get(att:String):String {
+	public function get(att:String):Null<String> {
 		if (nodeType != Element) {
 			throw 'Bad node type, expected Element but found $nodeType';
 		}
@@ -334,7 +334,7 @@ class Xml {
 	/**
 		Returns the first child node which is an Element.
 	**/
-	public function firstElement():Xml {
+	public function firstElement():Null<Xml> {
 		ensureElementType();
 		for (child in children) {
 			if (child.nodeType == Element) {

+ 2 - 2
std/cpp/_std/Std.hx

@@ -30,12 +30,12 @@
 		return untyped __global__.__instanceof(v, t);
 	}
 
-	@:keep public static function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
+	@:keep public static function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return Std.isOfType(value, c) ? cast value : null;
 	}
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	@:keep public static function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	@:keep public static function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return inline downcast(value, c);
 	}
 

+ 1 - 1
std/cpp/_std/Sys.hx

@@ -56,7 +56,7 @@ import haxe.SysTools;
 			return __global__.__get_args();
 		}
 
-	public static function getEnv(s:String):String {
+	public static function getEnv(s:String):Null<String> {
 		var v = NativeSys.get_env(s);
 		if (v == null)
 			return null;

+ 4 - 4
std/cpp/_std/Type.hx

@@ -46,14 +46,14 @@ enum ValueType {
 			return c;
 		}
 
-	public static function getEnum(o:EnumValue):Enum<Dynamic>
+	public static function getEnum(o:EnumValue):Null<Enum<Dynamic>>
 		untyped {
 			if (o == null)
 				return null;
 			return untyped o.__GetClass();
 		}
 
-	public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic>
+	public static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>>
 		untyped {
 			return c.GetSuper();
 		}
@@ -68,7 +68,7 @@ enum ValueType {
 		return untyped e.__ToString();
 	}
 
-	public static function resolveClass(name:String):Class<Dynamic>
+	public static function resolveClass(name:String):Null<Class<Dynamic>>
 		untyped {
 			var result:Class<Dynamic> = Class.Resolve(name);
 			if (result != null && result.__IsEnum())
@@ -76,7 +76,7 @@ enum ValueType {
 			return result;
 		}
 
-	public static function resolveEnum(name:String):Enum<Dynamic>
+	public static function resolveEnum(name:String):Null<Enum<Dynamic>>
 		untyped {
 			var result:Class<Dynamic> = Class.Resolve(name);
 			if (result != null && !result.__IsEnum())

+ 11 - 0
std/cpp/vm/Debugger.hx

@@ -321,6 +321,17 @@ class Debugger {
 			THREAD_NOT_STOPPED);
 	}
 
+	#if scriptable
+	/**
+		Sets the callback to run whenever a new CPPIA script is loaded.
+
+		This can be helpful for adding breakpoints to a script.
+	**/
+	public static function setOnScriptLoadedFunction(callback:Void->Void):Void {
+		untyped __global__.__hxcpp_dbg_setOnScriptLoadedFunction(callback);
+	}
+	#end
+
 	// The hxcpp runtime calls back through these functions to create Haxe
 	// objects as needed, which allows the C++ implementation code to create
 	// Haxe objects without having to actually know the structure of those

+ 1 - 1
std/eval/_std/Sys.hx

@@ -31,7 +31,7 @@ class Sys {
 
 	extern static public function args():Array<String>;
 
-	extern static public function getEnv(s:String):String;
+	extern static public function getEnv(s:String):Null<String>;
 
 	extern static public function putEnv(s:String, v:Null<String>):Void;
 

+ 2 - 2
std/flash/_std/Std.hx

@@ -32,12 +32,12 @@ import flash.Boot;
 		return flash.Boot.__instanceof(v, t);
 	}
 
-	public static inline function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return flash.Lib.as(value, c);
 	}
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return downcast(value, c);
 	}
 

+ 4 - 4
std/flash/_std/Type.hx

@@ -45,7 +45,7 @@ enum ValueType {
 			return c;
 		}
 
-	public static function getEnum(o:EnumValue):Enum<Dynamic>
+	public static function getEnum(o:EnumValue):Null<Enum<Dynamic>>
 		untyped {
 			var cname = __global__["flash.utils.getQualifiedClassName"](o);
 			if (cname == "null" || cname.substr(0, 8) == "builtin.")
@@ -59,7 +59,7 @@ enum ValueType {
 			return c;
 		}
 
-	public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic>
+	public static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>>
 		untyped {
 			var cname = __global__["flash.utils.getQualifiedSuperclassName"](c);
 			if (cname == null || cname == "Object")
@@ -92,7 +92,7 @@ enum ValueType {
 		return getClassName(cast e);
 	}
 
-	public static function resolveClass(name:String):Class<Dynamic>
+	public static function resolveClass(name:String):Null<Class<Dynamic>>
 		untyped {
 			var cl:Class<Dynamic>;
 			try {
@@ -115,7 +115,7 @@ enum ValueType {
 			return cl;
 		}
 
-	public static function resolveEnum(name:String):Enum<Dynamic>
+	public static function resolveEnum(name:String):Null<Enum<Dynamic>>
 		untyped {
 			var e:Dynamic;
 			try {

+ 1 - 1
std/flash/_std/haxe/Http.hx

@@ -40,7 +40,7 @@ class HttpFlash extends haxe.http.HttpBase {
 		req = null;
 	}
 
-	public override function request(?post:Bool) {
+	public override function request(post = false) {
 		responseAsString = null;
 		responseBytes = null;
 		var loader = req = new flash.net.URLLoader();

+ 2 - 2
std/haxe/Resource.hx

@@ -47,7 +47,7 @@ class Resource {
 
 		If `name` does not match any resource name, `null` is returned.
 	**/
-	public static function getString(name:String):String {
+	public static function getString(name:String):Null<String> {
 		for (x in content)
 			if (x.name == name) {
 				if (x.str != null)
@@ -64,7 +64,7 @@ class Resource {
 
 		If `name` does not match any resource name, `null` is returned.
 	**/
-	public static function getBytes(name:String):haxe.io.Bytes {
+	public static function getBytes(name:String):Null<haxe.io.Bytes> {
 		for (x in content)
 			if (x.name == name) {
 				if (x.str != null)

+ 2 - 1
std/haxe/Serializer.hx

@@ -243,7 +243,8 @@ class Serializer {
 	
 		All haxe-defined values and objects with the exception of functions can
 		be serialized. Serialization of external/native objects is not
-		guaranteed to work.
+		guaranteed to work. This is also true for classes extending external/native
+		classes. On some targets, this might include exceptions, too.
 	
 		The values of `this.useCache` and `this.useEnumIndex` may affect
 		serialization output.

+ 1 - 1
std/haxe/Template.hx

@@ -29,7 +29,7 @@ using StringTools;
 private enum TemplateExpr {
 	OpVar(v:String);
 	OpExpr(expr:Void->Dynamic);
-	OpIf(expr:Void->Dynamic, eif:TemplateExpr, eelse:TemplateExpr);
+	OpIf(expr:Void->Dynamic, eif:TemplateExpr, ?eelse:TemplateExpr);
 	OpStr(str:String);
 	OpBlock(l:List<TemplateExpr>);
 	OpForeach(expr:Void->Dynamic, loop:TemplateExpr);

+ 8 - 8
std/haxe/Unserializer.hx

@@ -28,8 +28,8 @@ import haxe.ds.List;
 
 @:noDoc
 typedef TypeResolver = {
-	function resolveClass(name:String):Class<Dynamic>;
-	function resolveEnum(name:String):Enum<Dynamic>;
+	function resolveClass(name:String):Null<Class<Dynamic>>;
+	function resolveEnum(name:String):Null<Enum<Dynamic>>;
 }
 
 /**
@@ -56,9 +56,9 @@ class Unserializer {
 
 		A type resolver must provide two methods:
 
-		1. `resolveClass(name:String):Class<Dynamic>` is called to determine a
+		1. `resolveClass(name:String):Null<Class<Dynamic>>` is called to determine a
 				`Class` from a class name
-		2. `resolveEnum(name:String):Enum<Dynamic>` is called to determine an
+		2. `resolveEnum(name:String):Null<Enum<Dynamic>>` is called to determine an
 				`Enum` from an enum name
 
 		This value is applied when a new `Unserializer` instance is created.
@@ -511,20 +511,20 @@ class Unserializer {
 private class DefaultResolver {
 	public function new() {}
 
-	public inline function resolveClass(name:String):Class<Dynamic>
+	public inline function resolveClass(name:String):Null<Class<Dynamic>>
 		return Type.resolveClass(name);
 
-	public inline function resolveEnum(name:String):Enum<Dynamic>
+	public inline function resolveEnum(name:String):Null<Enum<Dynamic>>
 		return Type.resolveEnum(name);
 }
 
 private class NullResolver {
 	function new() {}
 
-	public inline function resolveClass(name:String):Class<Dynamic>
+	public inline function resolveClass(name:String):Null<Class<Dynamic>>
 		return null;
 
-	public inline function resolveEnum(name:String):Enum<Dynamic>
+	public inline function resolveEnum(name:String):Null<Enum<Dynamic>>
 		return null;
 
 	public static var instance(get, null):NullResolver;

+ 1 - 1
std/haxe/format/JsonPrinter.hx

@@ -53,7 +53,7 @@ class JsonPrinter {
 	var pretty:Bool;
 	var nind:Int;
 
-	function new(replacer:(key:Dynamic, value:Dynamic) -> Dynamic, space:String) {
+	function new(replacer:Null<(key:Dynamic, value:Dynamic) -> Dynamic>, space:Null<String>) {
 		this.replacer = replacer;
 		this.indent = space;
 		this.pretty = space != null;

+ 1 - 1
std/haxe/http/HttpBase.hx

@@ -182,7 +182,7 @@ class HttpBase {
 		[js] If `this.async` is false, the callback functions are called before
 		this method returns.
 	**/
-	public function request(?post:Bool):Void {
+	public function request(post = false):Void {
 		throw new haxe.exceptions.NotImplementedException();
 	}
 

+ 1 - 1
std/haxe/http/HttpJs.hx

@@ -51,7 +51,7 @@ class HttpJs extends haxe.http.HttpBase {
 		req = null;
 	}
 
-	public override function request(?post:Bool) {
+	public override function request(post = false) {
 		this.responseAsString = null;
 		this.responseBytes = null;
 		this.responseHeaders = null;

+ 1 - 1
std/haxe/http/HttpNodeJs.hx

@@ -46,7 +46,7 @@ class HttpNodeJs extends haxe.http.HttpBase {
 		req = null;
 	}
 
-	public override function request(?post:Bool) {
+	public override function request(post = false) {
 		responseAsString = null;
 		responseBytes = null;
 		responseHeaders = null;

+ 1 - 1
std/haxe/io/BufferInput.hx

@@ -28,7 +28,7 @@ class BufferInput extends haxe.io.Input {
 	public var available:Int;
 	public var pos:Int;
 
-	public function new(i, buf, ?pos = 0, ?available = 0) {
+	public function new(i, buf, pos = 0, available = 0) {
 		this.i = i;
 		this.buf = buf;
 		this.pos = pos;

+ 1 - 1
std/haxe/macro/Printer.hx

@@ -38,7 +38,7 @@ class Printer {
 	var tabs:String;
 	var tabString:String;
 
-	public function new(?tabString = "\t") {
+	public function new(tabString = "\t") {
 		tabs = "";
 		this.tabString = tabString;
 	}

+ 1 - 1
std/haxe/xml/Printer.hx

@@ -32,7 +32,7 @@ class Printer {
 
 		Set `pretty` to `true` to prettify the result.
 	**/
-	static public function print(xml:Xml, ?pretty = false) {
+	static public function print(xml:Xml, pretty = false) {
 		var printer = new Printer(pretty);
 		printer.writeNode(xml, "");
 		return printer.output.toString();

+ 8 - 12
std/haxe/zip/Huffman.hx

@@ -22,10 +22,12 @@
 
 package haxe.zip;
 
+import haxe.ds.Vector;
+
 enum Huffman {
 	Found(i:Int);
 	NeedBit(left:Huffman, right:Huffman);
-	NeedBits(n:Int, table:Array<Huffman>);
+	NeedBits(n:Int, table:Vector<Huffman>);
 }
 
 class HuffTools {
@@ -52,14 +54,12 @@ class HuffTools {
 				default: throw "assert";
 			}
 		var size = 1 << d;
-		var table = new Array();
-		for (i in 0...size)
-			table.push(Found(-1));
+		var table = new Vector(size, Found(-1));
 		treeWalk(table, 0, 0, d, t);
 		return NeedBits(d, table);
 	}
 
-	function treeWalk(table, p, cd, d, t) {
+	function treeWalk(table:Vector<Huffman>, p, cd, d, t) {
 		switch (t) {
 			case NeedBit(a, b):
 				if (d > 0) {
@@ -83,18 +83,14 @@ class HuffTools {
 		return NeedBit(treeMake(bits, maxbits, v, len), treeMake(bits, maxbits, v | 1, len));
 	}
 
-	public function make(lengths, pos, nlengths, maxbits) {
+	public function make(lengths:Vector<Int>, pos, nlengths, maxbits) {
 		if (nlengths == 1) {
 			return NeedBit(Found(0), Found(0));
 		}
-		var counts = new Array();
-		var tmp = new Array();
 		if (maxbits > 32)
 			throw "Invalid huffman";
-		for (i in 0...maxbits) {
-			counts.push(0);
-			tmp.push(0);
-		}
+		var counts = new Vector(maxbits, 0);
+		var tmp = new Vector(maxbits, 0);
 		for (i in 0...nlengths) {
 			var p = lengths[i + pos];
 			if (p >= maxbits)

+ 10 - 13
std/haxe/zip/InflateImpl.hx

@@ -22,8 +22,9 @@
 
 package haxe.zip;
 
-import haxe.zip.Huffman;
 import haxe.crypto.Adler32;
+import haxe.ds.Vector;
+import haxe.zip.Huffman;
 
 private class Window {
 	public static inline var SIZE = 1 << 15;
@@ -121,12 +122,12 @@ class InflateImpl {
 	var output:haxe.io.Bytes;
 	var outpos:Int;
 	var input:haxe.io.Input;
-	var lengths:Array<Int>;
+	var lengths:Vector<Int>;
 	var window:Window;
 
 	static var FIXED_HUFFMAN = null;
 
-	public function new(i, ?header = true, ?crc = true) {
+	public function new(i, header = true, crc = true) {
 		isFinal = false;
 		htools = new HuffTools();
 		huffman = buildFixedHuffman();
@@ -140,18 +141,16 @@ class InflateImpl {
 		needed = 0;
 		output = null;
 		outpos = 0;
-		lengths = new Array();
-		for (i in 0...19)
-			lengths.push(-1);
+		lengths = new Vector(19, -1);
 		window = new Window(crc);
 	}
 
 	function buildFixedHuffman() {
 		if (FIXED_HUFFMAN != null)
 			return FIXED_HUFFMAN;
-		var a = new Array();
+		var a = new Vector(288);
 		for (n in 0...288)
-			a.push(if (n <= 143) 8 else if (n <= 255) 9 else if (n <= 279) 7 else 8);
+			a[n] = (if (n <= 143) 8 else if (n <= 255) 9 else if (n <= 279) 7 else 8);
 		FIXED_HUFFMAN = htools.make(a, 0, 288, 10);
 		return FIXED_HUFFMAN;
 	}
@@ -233,7 +232,7 @@ class InflateImpl {
 		}
 	}
 
-	function inflateLengths(a, max) {
+	function inflateLengths(a:Vector<Int>, max) {
 		var i = 0;
 		var prev = 0;
 		while (i < max) {
@@ -322,9 +321,7 @@ class InflateImpl {
 						for (i in hclen...19)
 							lengths[CODE_LENGTHS_POS[i]] = 0;
 						huffman = htools.make(lengths, 0, 19, 8);
-						var lengths = new Array();
-						for (i in 0...hlit + hdist)
-							lengths.push(0);
+						var lengths = new Vector(hlit + hdist, 0);
 						inflateLengths(lengths, hlit + hdist);
 						huffdist = htools.make(lengths, hlit, hdist, 16);
 						huffman = htools.make(lengths, 0, hlit, 16);
@@ -385,7 +382,7 @@ class InflateImpl {
 		}
 	}
 
-	public static function run(i:haxe.io.Input, ?bufsize = 65536) {
+	public static function run(i:haxe.io.Input, bufsize = 65536) {
 		var buf = haxe.io.Bytes.alloc(bufsize);
 		var output = new haxe.io.BytesBuffer();
 		var inflate = new InflateImpl(i);

+ 54 - 51
std/haxe/zip/Reader.hx

@@ -75,7 +75,7 @@ class Reader {
 		return fields;
 	}
 
-	public function readEntryHeader():Entry {
+	public function readEntryHeader():Null<Entry> {
 		var i = this.i;
 		var h = i.readInt32();
 		if (h == 0x02014B50 || h == 0x06054B50)
@@ -127,55 +127,59 @@ class Reader {
 			if (e == null)
 				break;
 			// do we have a data descriptor? (see readEntryHeader)
-			if (e.crc32 == null) {
-				if (e.compressed) {
-					#if neko
-					// enter progressive mode : we use a different input which has
-					// a temporary buffer, this is necessary since we have to uncompress
-					// progressively, and after that we might have pending read data
-					// that needs to be processed
-					var bufSize = 65536;
-					if (buf == null) {
-						buf = new haxe.io.BufferInput(i, haxe.io.Bytes.alloc(bufSize));
-						tmp = haxe.io.Bytes.alloc(bufSize);
-						i = buf;
-					}
-					var out = new haxe.io.BytesBuffer();
-					var z = new neko.zip.Uncompress(-15);
-					z.setFlushMode(neko.zip.Flush.SYNC);
-					while (true) {
-						if (buf.available == 0)
-							buf.refill();
-						var p = bufSize - buf.available;
-						if (p != buf.pos) {
-							// because of lack of "srcLen" in zip api, we need to always be stuck to the buffer end
-							buf.buf.blit(p, buf.buf, buf.pos, buf.available);
-							buf.pos = p;
-						}
-						var r = z.execute(buf.buf, buf.pos, tmp, 0);
-						out.addBytes(tmp, 0, r.write);
-						buf.pos += r.read;
-						buf.available -= r.read;
-						if (r.done)
-							break;
-					}
-					e.data = out.getBytes();
-					#else
-					var bufSize = 65536;
-					if (tmp == null)
-						tmp = haxe.io.Bytes.alloc(bufSize);
-					var out = new haxe.io.BytesBuffer();
-					var z = new InflateImpl(i, false, false);
-					while (true) {
-						var n = z.readBytes(tmp, 0, bufSize);
-						out.addBytes(tmp, 0, n);
-						if (n < bufSize)
-							break;
+			if (e.compressed) {
+				#if neko
+				// enter progressive mode : we use a different input which has
+				// a temporary buffer, this is necessary since we have to uncompress
+				// progressively, and after that we might have pending read data
+				// that needs to be processed
+				var bufSize = 65536;
+				if (buf == null) {
+					buf = new haxe.io.BufferInput(i, haxe.io.Bytes.alloc(bufSize));
+					tmp = haxe.io.Bytes.alloc(bufSize);
+					i = buf;
+				}
+				var out = new haxe.io.BytesBuffer();
+				var z = new neko.zip.Uncompress(-15);
+				z.setFlushMode(neko.zip.Flush.SYNC);
+				while (true) {
+					if (buf.available == 0)
+						buf.refill();
+					var p = bufSize - buf.available;
+					if (p != buf.pos) {
+						// because of lack of "srcLen" in zip api, we need to always be stuck to the buffer end
+						buf.buf.blit(p, buf.buf, buf.pos, buf.available);
+						buf.pos = p;
 					}
-					e.data = out.getBytes();
-					#end
-				} else
-					e.data = i.read(e.dataSize);
+					var r = z.execute(buf.buf, buf.pos, tmp, 0);
+					out.addBytes(tmp, 0, r.write);
+					buf.pos += r.read;
+					buf.available -= r.read;
+					if (r.done)
+						break;
+				}
+				e.data = out.getBytes();
+				e.compressed = false;
+				#else
+				var bufSize = 65536;
+				if (tmp == null)
+					tmp = haxe.io.Bytes.alloc(bufSize);
+				var out = new haxe.io.BytesBuffer();
+				var z = new InflateImpl(i, false, false);
+				while (true) {
+					var n = z.readBytes(tmp, 0, bufSize);
+					out.addBytes(tmp, 0, n);
+					if (n < bufSize)
+						break;
+				}
+				e.data = out.getBytes();
+				#end
+			} else
+				e.data = i.read(e.dataSize);
+
+			// If CRC32 is not defined in the header,
+			// it's defined in a data descriptor after the compressed data.
+			if (e.crc32 == null) {
 				e.crc32 = i.readInt32();
 				if (e.crc32 == 0x08074b50)
 					e.crc32 = i.readInt32();
@@ -184,8 +188,7 @@ class Reader {
 				// set data to uncompressed
 				e.dataSize = e.fileSize;
 				e.compressed = false;
-			} else
-				e.data = i.read(e.dataSize);
+			}
 			l.add(e);
 		}
 		return l;

+ 11 - 1
std/hl/CArray.hx

@@ -20,5 +20,15 @@ abstract CArray<T>(Abstract<"hl_carray">) {
 		return null;
 	}
 
+	#if (hl_ver >= version("1.16.0"))
+	public inline function blit( cl : Class<T>, pos : Int, src : CArray<T>, srcPos : Int, srcLen : Int ) : Void {
+		carray_blit( cast this, (cast cl:BaseType).__type__, pos, src, srcPos, srcLen );
+	}
+
+	@:hlNative("?std","carray_blit")
+	static function carray_blit( dst: CArray<Dynamic>, t : hl.Type, pos : Int, src : CArray<Dynamic>, srcPos : Int, srcLen : Int ) : Void {
+	}
+	#end
+
 }
-#end
+#end

+ 2 - 2
std/hl/_std/Std.hx

@@ -79,10 +79,10 @@ class Std {
 		return t.check(v);
 	}
 
-	extern public static function downcast<T:{}, S:T>(value:T, c:Class<S>):S;
+	extern public static function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S>;
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return downcast(value, c);
 	}
 

+ 1 - 1
std/hl/_std/Sys.hx

@@ -79,7 +79,7 @@ class Sys {
 		return @:privateAccess new sys.io.FileOutput(file_stderr());
 	}
 
-	public static function getEnv(s:String):String {
+	public static function getEnv(s:String):Null<String> {
 		var v = get_env(getPath(s));
 		if (v == null)
 			return null;

+ 4 - 4
std/hl/_std/Type.hx

@@ -93,14 +93,14 @@ class Type {
 		return null;
 	}
 
-	public static function getEnum(o:EnumValue):Enum<Dynamic> {
+	public static function getEnum(o:EnumValue):Null<Enum<Dynamic>> {
 		var t = hl.Type.getDynamic(o);
 		if (t.kind == HEnum)
 			return t.getGlobal();
 		return null;
 	}
 
-	public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic>@:privateAccess {
+	public static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>>@:privateAccess {
 		var c:hl.BaseType.Class = cast c;
 		var t = c.__type__.getSuper();
 		return t == hl.Type.void() ? null : t.getGlobal();
@@ -116,14 +116,14 @@ class Type {
 		return e.__ename__;
 	}
 
-	public static function resolveClass(name:String):Class<Dynamic> {
+	public static function resolveClass(name:String):Null<Class<Dynamic>> {
 		var t:hl.BaseType = allTypes.get(@:privateAccess name.bytes);
 		if (t == null || !Std.isOfType(t, hl.BaseType.Class))
 			return null;
 		return cast t;
 	}
 
-	public static function resolveEnum(name:String):Enum<Dynamic> {
+	public static function resolveEnum(name:String):Null<Enum<Dynamic>> {
 		var t:hl.BaseType = allTypes.get(@:privateAccess name.bytes);
 		if (t == null || !Std.isOfType(t, hl.BaseType.Enum))
 			return null;

+ 2 - 2
std/js/_std/Std.hx

@@ -34,12 +34,12 @@ import js.Syntax;
 		return @:privateAccess js.Boot.__instanceof(v, t);
 	}
 
-	public static inline function downcast<T:{}, S:T>(value:T, c:Class<S>):S @:privateAccess {
+	public static inline function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S> @:privateAccess {
 		return if (js.Boot.__downcastCheck(value, c)) cast value else null;
 	}
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return downcast(value, c);
 	}
 

+ 6 - 6
std/js/_std/Type.hx

@@ -36,7 +36,7 @@ enum ValueType {
 		return @:privateAccess js.Boot.getClass(o);
 	}
 
-	public static function getEnum(o:EnumValue):Enum<Dynamic>
+	public static function getEnum(o:EnumValue):Null<Enum<Dynamic>>
 		untyped {
 			if (o == null)
 				return null;
@@ -47,7 +47,7 @@ enum ValueType {
 			#end
 		}
 
-	public static inline function getSuperClass(c:Class<Dynamic>):Class<Dynamic> {
+	public static inline function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>> {
 		return untyped __define_feature__("Type.getSuperClass", c.__super__);
 	}
 
@@ -60,7 +60,7 @@ enum ValueType {
 	}
 
 	#if js_enums_as_arrays
-	public static function resolveClass(name:String):Class<Dynamic>
+	public static function resolveClass(name:String):Null<Class<Dynamic>>
 		untyped {
 			var cl:Class<Dynamic> = $hxClasses[name];
 			// ensure that this is a class
@@ -69,7 +69,7 @@ enum ValueType {
 			return cl;
 		}
 
-	public static function resolveEnum(name:String):Enum<Dynamic>
+	public static function resolveEnum(name:String):Null<Enum<Dynamic>>
 		untyped {
 			var e:Dynamic = $hxClasses[name];
 			// ensure that this is an enum
@@ -78,11 +78,11 @@ enum ValueType {
 			return e;
 		}
 	#else
-	public static inline function resolveClass(name:String):Class<Dynamic> {
+	public static inline function resolveClass(name:String):Null<Class<Dynamic>> {
 		return untyped __define_feature__("Type.resolveClass", $hxClasses[name]);
 	}
 
-	public static inline function resolveEnum(name:String):Enum<Dynamic> {
+	public static inline function resolveEnum(name:String):Null<Enum<Dynamic>> {
 		return untyped __define_feature__("Type.resolveEnum", $hxEnums[name]);
 	}
 	#end

+ 2 - 2
std/jvm/_std/Std.hx

@@ -182,12 +182,12 @@ class Std {
 		return try java.lang.Double.DoubleClass.parseDouble(x) catch (e:Dynamic) Math.NaN;
 	}
 
-	inline public static function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
+	inline public static function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return Std.isOfType(value, c) ? cast value : null;
 	}
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	inline public static function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	inline public static function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return downcast(value, c);
 	}
 

+ 1 - 1
std/jvm/_std/Sys.hx

@@ -47,7 +47,7 @@ using jvm.NativeTools;
 		return @:privateAccess Array.ofNative(_args);
 	}
 
-	public static function getEnv(s:String):String {
+	public static function getEnv(s:String):Null<String> {
 		return java.lang.System.getenv(s);
 	}
 

+ 4 - 4
std/jvm/_std/Type.hx

@@ -49,7 +49,7 @@ class Type {
 		return c.haxe();
 	}
 
-	public static function getEnum(o:EnumValue):Enum<Dynamic> {
+	public static function getEnum(o:EnumValue):Null<Enum<Dynamic>> {
 		if (o == null) {
 			return null;
 		}
@@ -60,7 +60,7 @@ class Type {
 		return c.haxeEnum();
 	}
 
-	public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic> {
+	public static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>> {
 		if (c == String) {
 			return null;
 		}
@@ -92,7 +92,7 @@ class Type {
 		}
 	}
 
-	public static function resolveClass(name:String):Class<Dynamic> {
+	public static function resolveClass(name:String):Null<Class<Dynamic>> {
 		if (name.indexOf(".") == -1) {
 			name = "haxe.root." + name;
 		}
@@ -107,7 +107,7 @@ class Type {
 		}
 	}
 
-	public static function resolveEnum(name:String):Enum<Dynamic> {
+	public static function resolveEnum(name:String):Null<Enum<Dynamic>> {
 		if (name.indexOf(".") == -1) {
 			name = "haxe.root." + name;
 		}

+ 2 - 2
std/lua/_std/Std.hx

@@ -34,12 +34,12 @@ import lua.NativeStringTools;
 		return untyped lua.Boot.__instanceof(v, t);
 	}
 
-	public static inline function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return untyped lua.Boot.__instanceof(value, c) ? cast value : null;
 	}
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return downcast(value, c);
 	}
 

+ 1 - 1
std/lua/_std/Sys.hx

@@ -94,7 +94,7 @@ class Sys {
 	public inline static function setCwd(s:String):Void
 		Misc.chdir(s);
 
-	public inline static function getEnv(s:String):String {
+	public inline static function getEnv(s:String):Null<String> {
 		return Os.getenv(s);
 	}
 

+ 4 - 4
std/lua/_std/Type.hx

@@ -43,14 +43,14 @@ enum ValueType {
 			return lua.Boot.getClass(o);
 		}
 
-	public static function getEnum(o:EnumValue):Enum<Dynamic>
+	public static function getEnum(o:EnumValue):Null<Enum<Dynamic>>
 		untyped {
 			if (o == null)
 				return null;
 			return o.__enum__;
 		}
 
-	public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic>
+	public static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>>
 		untyped {
 			return c.__super__;
 		}
@@ -65,7 +65,7 @@ enum ValueType {
 		return untyped e.__ename__;
 	}
 
-	public static function resolveClass(name:String):Class<Dynamic>
+	public static function resolveClass(name:String):Null<Class<Dynamic>>
 		untyped {
 			// TODO: better tmp name for _hxClasses
 			var cl:Class<Dynamic> = _hxClasses[name];
@@ -75,7 +75,7 @@ enum ValueType {
 			return cl;
 		}
 
-	public static function resolveEnum(name:String):Enum<Dynamic>
+	public static function resolveEnum(name:String):Null<Enum<Dynamic>>
 		untyped {
 			// TODO: better tmp name for _hxClasses
 			var e:Dynamic = _hxClasses[name];

+ 2 - 2
std/neko/_std/Std.hx

@@ -30,12 +30,12 @@
 		return untyped neko.Boot.__instanceof(v, t);
 	}
 
-	public static function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return Std.isOfType(value, c) ? cast value : null;
 	}
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	public static function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return inline downcast(value, c);
 	}
 

+ 1 - 1
std/neko/_std/Sys.hx

@@ -62,7 +62,7 @@ import haxe.SysTools;
 		return r;
 	}
 
-	public static function getEnv( s : String ) : String {
+	public static function getEnv( s : String ) : Null<String> {
 		var v = get_env(untyped s.__s);
 		if( v == null )
 			return null;

+ 4 - 4
std/neko/_std/Type.hx

@@ -43,14 +43,14 @@ enum ValueType {
 		return p.__class__;
 	}
 
-	public static function getEnum( o : EnumValue ) : Enum<Dynamic> untyped {
+	public static function getEnum( o : EnumValue ) : Null<Enum<Dynamic>> untyped {
 		if( __dollar__typeof(o) != __dollar__tobject )
 			return null;
 		return o.__enum__;
 	}
 
 
-	public static function getSuperClass( c : Class<Dynamic> ) : Class<Dynamic> untyped {
+	public static function getSuperClass( c : Class<Dynamic> ) : Null<Class<Dynamic>> untyped {
 		return c.__super__;
 	}
 
@@ -67,7 +67,7 @@ enum ValueType {
 		return a.join(".");
 	}
 
-	public static function resolveClass( name : String ) : Class<Dynamic> untyped {
+	public static function resolveClass( name : String ) : Null<Class<Dynamic>> untyped {
 		var path = name.split(".");
 		var cl = Reflect.field(untyped neko.Boot.__classes,path[0]);
 		var i = 1;
@@ -82,7 +82,7 @@ enum ValueType {
 	}
 
 
-	public static function resolveEnum( name : String ) : Enum<Dynamic> untyped {
+	public static function resolveEnum( name : String ) : Null<Enum<Dynamic>> untyped {
 		var path = name.split(".");
 		var e = Reflect.field(neko.Boot.__classes,path[0]);
 		var i = 1;

+ 2 - 2
std/php/_std/Std.hx

@@ -34,12 +34,12 @@ import php.Syntax;
 		return Boot.isOfType(v, t);
 	}
 
-	public static inline function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return Boot.isOfType(value, cast c) ? cast value : null;
 	}
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return Boot.isOfType(value, cast c) ? cast value : null;
 	}
 

+ 1 - 1
std/php/_std/StringTools.hx

@@ -33,7 +33,7 @@ import haxe.iterators.StringKeyValueIterator;
 		return Global.urldecode(s);
 	}
 
-	public inline static function htmlEscape(s:String, ?quotes:Bool):String {
+	public inline static function htmlEscape(s:String, quotes:Bool = false):String {
 		return Global.htmlspecialchars(s, (quotes ? Const.ENT_QUOTES | Const.ENT_HTML401 : Const.ENT_NOQUOTES));
 	}
 

+ 1 - 1
std/php/_std/Sys.hx

@@ -82,7 +82,7 @@ import haxe.SysTools;
 		}
 	}
 
-	public static function getEnv(s:String):String {
+	public static function getEnv(s:String):Null<String> {
 		var value = Global.getenv(s);
 		return value == false ? null : value;
 	}

+ 4 - 4
std/php/_std/Type.hx

@@ -50,13 +50,13 @@ enum ValueType {
 		}
 	}
 
-	public static function getEnum(o:EnumValue):Enum<Dynamic> {
+	public static function getEnum(o:EnumValue):Null<Enum<Dynamic>> {
 		if (o == null)
 			return null;
 		return cast Boot.getClass(Global.get_class(cast o));
 	}
 
-	public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic> {
+	public static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>> {
 		if (c == null)
 			return null;
 		var parentClass = try {
@@ -79,7 +79,7 @@ enum ValueType {
 		return getClassName(cast e);
 	}
 
-	public static function resolveClass(name:String):Class<Dynamic> {
+	public static function resolveClass(name:String):Null<Class<Dynamic>> {
 		if (name == null)
 			return null;
 		switch (name) {
@@ -108,7 +108,7 @@ enum ValueType {
 		return cast hxClass;
 	}
 
-	public static function resolveEnum(name:String):Enum<Dynamic> {
+	public static function resolveEnum(name:String):Null<Enum<Dynamic>> {
 		if (name == null)
 			return null;
 		if (name == 'Bool')

+ 1 - 1
std/python/Boot.hx

@@ -395,7 +395,7 @@ class Boot {
 		}
 	}
 
-	static function getSuperClass(c:Class<Dynamic>):Class<Dynamic> {
+	static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>> {
 		if (c == null)
 			return null;
 

+ 2 - 2
std/python/_std/Std.hx

@@ -31,7 +31,7 @@ import python.Syntax;
 @:keepInit
 @:coreApi class Std {
 	@:access(python.Boot)
-	public static function downcast<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static function downcast<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		try {
 			return UBuiltins.isinstance(value, c) || (Inspect.isInterface(c) && Boot.implementsInterface(value, c)) ? cast value : null;
 		} catch (e:Dynamic) {
@@ -40,7 +40,7 @@ import python.Syntax;
 	}
 
 	@:deprecated('Std.instance() is deprecated. Use Std.downcast() instead.')
-	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):S {
+	public static inline function instance<T:{}, S:T>(value:T, c:Class<S>):Null<S> {
 		return downcast(value, c);
 	}
 

+ 1 - 1
std/python/_std/Sys.hx

@@ -49,7 +49,7 @@ class Sys {
 		return argv.slice(1);
 	}
 
-	public static function getEnv(s:String):String {
+	public static function getEnv(s:String):Null<String> {
 		return Os.environ.get(s, null);
 	}
 

+ 4 - 4
std/python/_std/Type.hx

@@ -60,13 +60,13 @@ enum ValueType {
 		}
 	}
 
-	public static function getEnum(o:EnumValue):Enum<Dynamic> {
+	public static function getEnum(o:EnumValue):Null<Enum<Dynamic>> {
 		if (o == null)
 			return null;
 		return Syntax.field(o, "__class__");
 	}
 
-	public static function getSuperClass(c:Class<Dynamic>):Class<Dynamic> {
+	public static function getSuperClass(c:Class<Dynamic>):Null<Class<Dynamic>> {
 		return python.Boot.getSuperClass(c);
 	}
 
@@ -94,7 +94,7 @@ enum ValueType {
 		return Internal.fieldClassName(e);
 	}
 
-	public static function resolveClass(name:String):Class<Dynamic> {
+	public static function resolveClass(name:String):Null<Class<Dynamic>> {
 		if (name == "Array")
 			return Array;
 		if (name == "Math")
@@ -109,7 +109,7 @@ enum ValueType {
 		return cl;
 	}
 
-	public static function resolveEnum(name:String):Enum<Dynamic> {
+	public static function resolveEnum(name:String):Null<Enum<Dynamic>> {
 		if (name == "Bool")
 			return cast Bool;
 		var o = resolveClass(name);

+ 1 - 1
std/sys/Http.hx

@@ -55,7 +55,7 @@ class Http extends haxe.http.HttpBase {
 		super(url);
 	}
 
-	public override function request(?post:Bool) {
+	public override function request(post = false) {
 		var output = new haxe.io.BytesOutput();
 		var old = onError;
 		var err = false;

+ 1 - 1
tests/misc/projects/Issue10147/Main.hx

@@ -5,7 +5,7 @@ typedef HasANullString = {
 	text:Null<String>
 }
 
-@:nullSafety(StrictThreaded)
+@:nullSafety
 class Main {
 	static function main() {
 		final has:HasAString = {text: null};

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

@@ -1,3 +1,4 @@
+Main.hx:11: characters 3-39 : Null safety: Cannot assign nullable value here.
 Main.hx:14: characters 3-32 : Null safety: Cannot unify { text : Null<String> } with HasAString
 Main.hx:17: characters 3-35 : Null safety: Cannot unify { text : Null<String> } with { text : String }
 Main.hx:20: characters 30-38 : Null safety: Cannot use nullable value of Null<String> as an item in Array<String>

+ 14 - 0
tests/misc/projects/Issue10782/ArrayAccess.hx

@@ -0,0 +1,14 @@
+class C {
+	public function new() {}
+
+	public function call() {
+		trace("called!");
+	}
+}
+
+function main() {
+	final f = function() {
+		trace("f!");
+	}
+	[new C()][0].call();
+}

+ 22 - 0
tests/misc/projects/Issue10782/Main.hx

@@ -0,0 +1,22 @@
+@:callable
+abstract Function(Int->Int) to Int->Int from Int->Int {
+	@:op(a * b)
+	static inline function chain(a:Function, b:Function):Function {
+		return function(i) {
+			return a(b(i));
+		};
+	}
+}
+
+class Main {
+	static function main() {
+		var f:Function = function(a) {
+			return a + 1;
+		};
+
+		var g = function(a) { return a * a; } * f;
+		if (g(10) != 121) {
+			throw "Incorrect function return value";
+		}
+	}
+}

+ 7 - 0
tests/misc/projects/Issue10782/NoPostfix.hx

@@ -0,0 +1,7 @@
+function main() {
+	var i = 0;
+	final f = function() {
+		trace("f!");
+	}
+	--i;
+}

+ 1 - 0
tests/misc/projects/Issue10782/compile-array-access.hxml

@@ -0,0 +1 @@
+--run ArrayAccess

+ 1 - 0
tests/misc/projects/Issue10782/compile-array-access.hxml.stdout

@@ -0,0 +1 @@
+ArrayAccess.hx:5: called!

+ 1 - 0
tests/misc/projects/Issue10782/compile-no-postfix.hxml

@@ -0,0 +1 @@
+--run NoPostfix

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

@@ -0,0 +1 @@
+--run Main

+ 5 - 0
tests/misc/projects/Issue11164/Macro.hx

@@ -0,0 +1,5 @@
+class Macro {
+	public static function build() {
+		return macro :Any;
+	}
+}

+ 29 - 0
tests/misc/projects/Issue11164/Main.hx

@@ -0,0 +1,29 @@
+typedef A<K = String, V> = haxe.ds.BalancedTree<K,V>;
+
+class B<T1 = Int, T2 = String, T3> {}
+
+class DefaultGeneric<T = String> {
+	public function new() {}
+}
+
+class Main {
+	static function main() {
+		var a:A<default,Int> = null;
+		$type(a);
+
+		var b:B<Bool,default,Int> = null;
+		$type(b);
+
+		var c = new DefaultGeneric();
+		$type(c);
+
+		var d = new DefaultGeneric<default>();
+		$type(d);
+
+		var e:DefaultGeneric = new DefaultGeneric();
+		$type(e);
+
+		var f:DefaultGeneric<default> = new DefaultGeneric();
+		$type(f);
+	}
+}

+ 5 - 0
tests/misc/projects/Issue11164/Main2.hx

@@ -0,0 +1,5 @@
+class Main2 {
+	static function main() {
+		var b:Array<default> = [];
+	}
+}

+ 3 - 0
tests/misc/projects/Issue11164/Main3.hx

@@ -0,0 +1,3 @@
+typedef B = default;
+
+function main() {}

+ 3 - 0
tests/misc/projects/Issue11164/Main4.hx

@@ -0,0 +1,3 @@
+typedef default = String;
+
+function main() {}

+ 3 - 0
tests/misc/projects/Issue11164/Main5.hx

@@ -0,0 +1,3 @@
+function main() {
+	var a:default;
+}

+ 2 - 0
tests/misc/projects/Issue11164/Main6.hx

@@ -0,0 +1,2 @@
+typedef Foo = Array<String, default>
+function main() {}

+ 5 - 0
tests/misc/projects/Issue11164/Main7.hx

@@ -0,0 +1,5 @@
+@:genericBuild(Macro.build())
+private class Foo<Rest> {}
+private typedef Bar = Foo<Int, default>
+
+function main() {}

+ 3 - 0
tests/misc/projects/Issue11164/compile.hxml

@@ -0,0 +1,3 @@
+-main Main
+-D message.reporting=pretty
+-D message.no-color

+ 36 - 0
tests/misc/projects/Issue11164/compile.hxml.stderr

@@ -0,0 +1,36 @@
+[WARNING] Main.hx:12: characters 9-10
+
+ 12 |   $type(a);
+    |         ^
+    | A<String, Int>
+
+[WARNING] Main.hx:15: characters 9-10
+
+ 15 |   $type(b);
+    |         ^
+    | B<Bool, String, Int>
+
+[WARNING] Main.hx:18: characters 9-10
+
+ 18 |   $type(c);
+    |         ^
+    | DefaultGeneric<Unknown<0>>
+
+[WARNING] Main.hx:21: characters 9-10
+
+ 21 |   $type(d);
+    |         ^
+    | DefaultGeneric<String>
+
+[WARNING] Main.hx:24: characters 9-10
+
+ 24 |   $type(e);
+    |         ^
+    | DefaultGeneric<String>
+
+[WARNING] Main.hx:27: characters 9-10
+
+ 27 |   $type(f);
+    |         ^
+    | DefaultGeneric<String>
+

+ 3 - 0
tests/misc/projects/Issue11164/compile2-fail.hxml

@@ -0,0 +1,3 @@
+-main Main2
+-D message.reporting=pretty
+-D message.no-color

+ 6 - 0
tests/misc/projects/Issue11164/compile2-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Main2.hx:3: characters 15-22
+
+ 3 |   var b:Array<default> = [];
+   |               ^^^^^^^
+   | Invalid default, type parameter T has no default value
+

+ 3 - 0
tests/misc/projects/Issue11164/compile3-fail.hxml

@@ -0,0 +1,3 @@
+-main Main3
+-D message.reporting=pretty
+-D message.no-color

+ 6 - 0
tests/misc/projects/Issue11164/compile3-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Main3.hx:1: characters 13-20
+
+ 1 | typedef B = default;
+   |             ^^^^^^^
+   | Invalid type : default
+

+ 3 - 0
tests/misc/projects/Issue11164/compile4-fail.hxml

@@ -0,0 +1,3 @@
+-main Main4
+-D message.reporting=pretty
+-D message.no-color

+ 6 - 0
tests/misc/projects/Issue11164/compile4-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Main4.hx:1: characters 9-16
+
+ 1 | typedef default = String;
+   |         ^^^^^^^
+   | Unexpected keyword "default"
+

+ 3 - 0
tests/misc/projects/Issue11164/compile5-fail.hxml

@@ -0,0 +1,3 @@
+-main Main5
+-D message.reporting=pretty
+-D message.no-color

+ 6 - 0
tests/misc/projects/Issue11164/compile5-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Main5.hx:2: characters 8-15
+
+ 2 |  var a:default;
+   |        ^^^^^^^
+   | Invalid type : default
+

+ 3 - 0
tests/misc/projects/Issue11164/compile6-fail.hxml

@@ -0,0 +1,3 @@
+-main Main6
+-D message.reporting=pretty
+-D message.no-color

+ 6 - 0
tests/misc/projects/Issue11164/compile6-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Main6.hx:1: characters 29-36
+
+ 1 | typedef Foo = Array<String, default>
+   |                             ^^^^^^^
+   | Too many type parameters for Array
+

+ 3 - 0
tests/misc/projects/Issue11164/compile7-fail.hxml

@@ -0,0 +1,3 @@
+-main Main7
+-D message.reporting=pretty
+-D message.no-color

+ 6 - 0
tests/misc/projects/Issue11164/compile7-fail.hxml.stderr

@@ -0,0 +1,6 @@
+[ERROR] Main7.hx:3: characters 32-39
+
+ 3 | private typedef Bar = Foo<Int, default>
+   |                                ^^^^^^^
+   | Cannot use default with rest type parameters
+

+ 2 - 0
tests/misc/projects/Issue11389/Main.hx

@@ -0,0 +1,2 @@
+function main() {}
+@:native("")

部分文件因文件數量過多而無法顯示