Explorar o código

Make ctx.pass immutable (#11538)

* remove @:enumConstructorParam

* remove init_class_done

see if this breaks anything

* clone for expr

* make ctx.pass immutable

* ctx.e can be immutable too

* add failing test to show everyone that it's broken

* fix it

* inherit allow_inline and allow_transform to contexts within the same module
Simon Krajewski hai 1 ano
pai
achega
3f13b750ba

+ 0 - 7
src-json/meta.json

@@ -295,13 +295,6 @@
 		"targets": ["TAbstract"],
 		"targets": ["TAbstract"],
 		"links": ["https://haxe.org/manual/types-abstract-enum.html"]
 		"links": ["https://haxe.org/manual/types-abstract-enum.html"]
 	},
 	},
-	{
-		"name": "EnumConstructorParam",
-		"metadata": ":enumConstructorParam",
-		"doc": "Used internally to annotate GADT type parameters.",
-		"targets": ["TClass"],
-		"internal": true
-	},
 	{
 	{
 		"name": "Event",
 		"name": "Event",
 		"metadata": ":event",
 		"metadata": ":event",

+ 1 - 1
src/codegen/gencommon/normalize.ml

@@ -31,7 +31,7 @@ open Gencommon
 
 
 let rec filter_param (stack:t list) t =
 let rec filter_param (stack:t list) t =
 	match t with
 	match t with
-	| TInst({ cl_kind = KTypeParameter _ } as c,_) when Meta.has Meta.EnumConstructorParam c.cl_meta ->
+	| TInst({ cl_kind = KTypeParameter ttp },_) when ttp.ttp_host = TPHEnumConstructor ->
 		t_dynamic
 		t_dynamic
 	| TMono r ->
 	| TMono r ->
 		(match r.tm_type with
 		(match r.tm_type with

+ 17 - 22
src/context/typecore.ml

@@ -169,8 +169,8 @@ and typer = {
 	mutable m : typer_module;
 	mutable m : typer_module;
 	c : typer_class;
 	c : typer_class;
 	f : typer_field;
 	f : typer_field;
-	mutable e : typer_expr;
-	mutable pass : typer_pass;
+	e : typer_expr;
+	pass : typer_pass;
 	mutable type_params : type_params;
 	mutable type_params : type_params;
 	mutable allow_inline : bool;
 	mutable allow_inline : bool;
 	mutable allow_transform : bool;
 	mutable allow_transform : bool;
@@ -183,7 +183,7 @@ and monomorphs = {
 }
 }
 
 
 module TyperManager = struct
 module TyperManager = struct
-	let create com g m c f e pass params = {
+	let create com g m c f e pass params allow_inline allow_transform = {
 		com = com;
 		com = com;
 		g = g;
 		g = g;
 		t = com.basic;
 		t = com.basic;
@@ -192,8 +192,8 @@ module TyperManager = struct
 		f = f;
 		f = f;
 		e = e;
 		e = e;
 		pass = pass;
 		pass = pass;
-		allow_inline = true;
-		allow_transform = true;
+		allow_inline;
+		allow_transform;
 		type_params = params;
 		type_params = params;
 		memory_marker = memory_marker;
 		memory_marker = memory_marker;
 	}
 	}
@@ -244,42 +244,46 @@ module TyperManager = struct
 		let c = create_ctx_c null_class in
 		let c = create_ctx_c null_class in
 		let f = create_ctx_f null_field in
 		let f = create_ctx_f null_field in
 		let e = create_ctx_e () in
 		let e = create_ctx_e () in
-		create com g m c f e PBuildModule []
+		create com g m c f e PBuildModule [] true true
 
 
 	let clone_for_class ctx c =
 	let clone_for_class ctx c =
 		let c = create_ctx_c c in
 		let c = create_ctx_c c in
 		let f = create_ctx_f null_field in
 		let f = create_ctx_f null_field in
 		let e = create_ctx_e () in
 		let e = create_ctx_e () in
 		let params = match c.curclass.cl_kind with KAbstractImpl a -> a.a_params | _ -> c.curclass.cl_params in
 		let params = match c.curclass.cl_kind with KAbstractImpl a -> a.a_params | _ -> c.curclass.cl_params in
-		create ctx.com ctx.g ctx.m c f e PBuildClass params
+		create ctx.com ctx.g ctx.m c f e PBuildClass params ctx.allow_inline ctx.allow_transform
 
 
 	let clone_for_enum ctx en =
 	let clone_for_enum ctx en =
 		let c = create_ctx_c null_class in
 		let c = create_ctx_c null_class in
 		let f = create_ctx_f null_field in
 		let f = create_ctx_f null_field in
 		let e = create_ctx_e () in
 		let e = create_ctx_e () in
-		create ctx.com ctx.g ctx.m c f e PBuildModule en.e_params
+		create ctx.com ctx.g ctx.m c f e PBuildModule en.e_params ctx.allow_inline ctx.allow_transform
 
 
 	let clone_for_typedef ctx td =
 	let clone_for_typedef ctx td =
 		let c = create_ctx_c null_class in
 		let c = create_ctx_c null_class in
 		let f = create_ctx_f null_field in
 		let f = create_ctx_f null_field in
 		let e = create_ctx_e () in
 		let e = create_ctx_e () in
-		create ctx.com ctx.g ctx.m c f e PBuildModule td.t_params
+		create ctx.com ctx.g ctx.m c f e PBuildModule td.t_params ctx.allow_inline ctx.allow_transform
 
 
 	let clone_for_abstract ctx a =
 	let clone_for_abstract ctx a =
 		let c = create_ctx_c null_class in
 		let c = create_ctx_c null_class in
 		let f = create_ctx_f null_field in
 		let f = create_ctx_f null_field in
 		let e = create_ctx_e () in
 		let e = create_ctx_e () in
-		create ctx.com ctx.g ctx.m c f e PBuildModule a.a_params
+		create ctx.com ctx.g ctx.m c f e PBuildModule a.a_params ctx.allow_inline ctx.allow_transform
 
 
 	let clone_for_field ctx cf params =
 	let clone_for_field ctx cf params =
 		let f = create_ctx_f cf in
 		let f = create_ctx_f cf in
 		let e = create_ctx_e () in
 		let e = create_ctx_e () in
-		create ctx.com ctx.g ctx.m ctx.c f e PBuildClass params
+		create ctx.com ctx.g ctx.m ctx.c f e PBuildClass params ctx.allow_inline ctx.allow_transform
 
 
 	let clone_for_enum_field ctx params =
 	let clone_for_enum_field ctx params =
 		let f = create_ctx_f null_field in
 		let f = create_ctx_f null_field in
 		let e = create_ctx_e () in
 		let e = create_ctx_e () in
-		create ctx.com ctx.g ctx.m ctx.c f e PBuildClass params
+		create ctx.com ctx.g ctx.m ctx.c f e PBuildClass params ctx.allow_inline ctx.allow_transform
+
+	let clone_for_expr ctx =
+		let e = create_ctx_e () in
+		create ctx.com ctx.g ctx.m ctx.c ctx.f e PTypeField ctx.type_params ctx.allow_inline ctx.allow_transform
 end
 end
 
 
 type field_host =
 type field_host =
@@ -559,12 +563,8 @@ let rec flush_pass ctx p where =
 
 
 let make_pass ctx f = f
 let make_pass ctx f = f
 
 
-let init_class_done ctx =
-	ctx.pass <- PConnectField
-
 let enter_field_typing_pass ctx info =
 let enter_field_typing_pass ctx info =
-	flush_pass ctx PConnectField info;
-	ctx.pass <- PTypeField
+	flush_pass ctx PConnectField info
 
 
 let make_lazy ?(force=true) ctx t_proc f where =
 let make_lazy ?(force=true) ctx t_proc f where =
 	let r = ref (lazy_available t_dynamic) in
 	let r = ref (lazy_available t_dynamic) in
@@ -909,11 +909,6 @@ let debug com (path : string list) str =
 			if List.exists (Ast.match_path false path) debug_paths then emit();
 			if List.exists (Ast.match_path false path) debug_paths then emit();
 	end
 	end
 
 
-let init_class_done ctx =
-	let path = fst ctx.c.curclass.cl_path @ [snd ctx.c.curclass.cl_path] in
-	debug ctx.com path ("init_class_done " ^ s_type_path ctx.c.curclass.cl_path);
-	init_class_done ctx
-
 let ctx_pos ctx =
 let ctx_pos ctx =
 	let inf = fst ctx.m.curmod.m_path @ [snd ctx.m.curmod.m_path]in
 	let inf = fst ctx.m.curmod.m_path @ [snd ctx.m.curmod.m_path]in
 	let inf = (match snd ctx.c.curclass.cl_path with "" -> inf | n when n = snd ctx.m.curmod.m_path -> inf | n -> inf @ [n]) in
 	let inf = (match snd ctx.c.curclass.cl_path with "" -> inf | n when n = snd ctx.m.curmod.m_path -> inf | n -> inf @ [n]) in

+ 8 - 8
src/typing/functionArguments.ml

@@ -4,7 +4,7 @@ open Type
 open Typecore
 open Typecore
 open Error
 open Error
 
 
-let type_function_arg ctx t e opt p =
+let type_function_arg com t e opt p =
 	(* TODO https://github.com/HaxeFoundation/haxe/issues/8461 *)
 	(* TODO https://github.com/HaxeFoundation/haxe/issues/8461 *)
 	(* delay ctx PTypeField (fun() ->
 	(* delay ctx PTypeField (fun() ->
 		if ExtType.is_void (follow t) then
 		if ExtType.is_void (follow t) then
@@ -12,9 +12,9 @@ let type_function_arg ctx t e opt p =
 	); *)
 	); *)
 	if opt then
 	if opt then
 		let e = (match e with None -> Some (EConst (Ident "null"),null_pos) | _ -> e) in
 		let e = (match e with None -> Some (EConst (Ident "null"),null_pos) | _ -> e) in
-		ctx.t.tnull t, e
+		com.Common.basic.tnull t, e
 	else
 	else
-		let t = match e with Some (EConst (Ident "null"),null_pos) -> ctx.t.tnull t | _ -> t in
+		let t = match e with Some (EConst (Ident "null"),null_pos) -> com.basic.tnull t | _ -> t in
 		t, e
 		t, e
 
 
 let type_function_arg_value ctx t c do_display =
 let type_function_arg_value ctx t c do_display =
@@ -38,7 +38,7 @@ let type_function_arg_value ctx t c do_display =
 			loop e
 			loop e
 
 
 class function_arguments
 class function_arguments
-	(ctx : typer)
+	(com : Common.context)
 	(type_arg : int -> bool -> type_hint option -> pos -> Type.t)
 	(type_arg : int -> bool -> type_hint option -> pos -> Type.t)
 	(is_extern : bool)
 	(is_extern : bool)
 	(do_display : bool)
 	(do_display : bool)
@@ -48,7 +48,7 @@ class function_arguments
 	let with_default =
 	let with_default =
 		let l = List.mapi (fun i ((name,pn),opt,_,t,eo) ->
 		let l = List.mapi (fun i ((name,pn),opt,_,t,eo) ->
 			let t = type_arg i opt t pn in
 			let t = type_arg i opt t pn in
-			let t,eo = type_function_arg ctx t eo opt pn in
+			let t,eo = type_function_arg com t eo opt pn in
 			(name,eo,t)
 			(name,eo,t)
 		) syntax in
 		) syntax in
 		let l = match abstract_this with
 		let l = match abstract_this with
@@ -83,7 +83,7 @@ object(self)
 
 
 	(* Returns the `(tvar * texpr option) list` for `tf_args`. Also checks the validity of argument names and whether or not
 	(* Returns the `(tvar * texpr option) list` for `tf_args`. Also checks the validity of argument names and whether or not
 	   an argument should be displayed. *)
 	   an argument should be displayed. *)
-	method for_expr = match expr_repr with
+	method for_expr ctx = match expr_repr with
 		| Some l ->
 		| Some l ->
 			l
 			l
 		| None ->
 		| None ->
@@ -116,7 +116,7 @@ object(self)
 			l
 			l
 
 
 	(* Verifies the validity of any argument typed as `haxe.extern.Rest` and checks default values. *)
 	(* Verifies the validity of any argument typed as `haxe.extern.Rest` and checks default values. *)
-	method verify_extern =
+	method verify_extern ctx =
 		let rec loop is_abstract_this syntax typed = match syntax,typed with
 		let rec loop is_abstract_this syntax typed = match syntax,typed with
 			| syntax,(name,_,t) :: typed when is_abstract_this ->
 			| syntax,(name,_,t) :: typed when is_abstract_this ->
 				loop false syntax typed
 				loop false syntax typed
@@ -135,5 +135,5 @@ object(self)
 	method bring_into_context ctx =
 	method bring_into_context ctx =
 		List.iter (fun (v,_) ->
 		List.iter (fun (v,_) ->
 			ctx.f.locals <- PMap.add v.v_name v ctx.f.locals
 			ctx.f.locals <- PMap.add v.v_name v ctx.f.locals
-		) self#for_expr
+		) (self#for_expr ctx)
 end
 end

+ 15 - 13
src/typing/macroContext.ml

@@ -57,7 +57,7 @@ let macro_timer com l =
 
 
 let typing_timer ctx need_type f =
 let typing_timer ctx need_type f =
 	let t = Timer.timer ["typing"] in
 	let t = Timer.timer ["typing"] in
-	let old = ctx.com.error_ext and oldp = ctx.pass and oldlocals = ctx.f.locals in
+	let old = ctx.com.error_ext and oldlocals = ctx.f.locals in
 	let restore_report_mode = disable_report_mode ctx.com in
 	let restore_report_mode = disable_report_mode ctx.com in
 	(*
 	(*
 		disable resumable errors... unless we are in display mode (we want to reach point of completion)
 		disable resumable errors... unless we are in display mode (we want to reach point of completion)
@@ -65,18 +65,20 @@ let typing_timer ctx need_type f =
 	(* if ctx.com.display.dms_kind = DMNone then ctx.com.error <- (fun e -> raise_error e); *) (* TODO: review this... *)
 	(* if ctx.com.display.dms_kind = DMNone then ctx.com.error <- (fun e -> raise_error e); *) (* TODO: review this... *)
 	ctx.com.error_ext <- (fun err -> raise_error { err with err_from_macro = true });
 	ctx.com.error_ext <- (fun err -> raise_error { err with err_from_macro = true });
 
 
-	if need_type && ctx.pass < PTypeField then begin
+	let ctx = if need_type && ctx.pass < PTypeField then begin
 		enter_field_typing_pass ctx ("typing_timer",[] (* TODO: ? *));
 		enter_field_typing_pass ctx ("typing_timer",[] (* TODO: ? *));
-	end;
+		TyperManager.clone_for_expr ctx
+	end else
+		ctx
+	in
 	let exit() =
 	let exit() =
 		t();
 		t();
 		ctx.com.error_ext <- old;
 		ctx.com.error_ext <- old;
-		ctx.pass <- oldp;
 		ctx.f.locals <- oldlocals;
 		ctx.f.locals <- oldlocals;
 		restore_report_mode ();
 		restore_report_mode ();
 	in
 	in
 	try
 	try
-		let r = f() in
+		let r = f ctx in
 		exit();
 		exit();
 		r
 		r
 	with Error err ->
 	with Error err ->
@@ -322,7 +324,7 @@ let make_macro_api ctx mctx p =
 	{
 	{
 		com_api with
 		com_api with
 		MacroApi.get_type = (fun s ->
 		MacroApi.get_type = (fun s ->
-			typing_timer ctx false (fun() ->
+			typing_timer ctx false (fun ctx ->
 				let path = parse_path s in
 				let path = parse_path s in
 				let tp = match List.rev (fst path) with
 				let tp = match List.rev (fst path) with
 					| s :: sl when String.length s > 0 && (match s.[0] with 'A'..'Z' -> true | _ -> false) ->
 					| s :: sl when String.length s > 0 && (match s.[0] with 'A'..'Z' -> true | _ -> false) ->
@@ -338,10 +340,10 @@ let make_macro_api ctx mctx p =
 			)
 			)
 		);
 		);
 		MacroApi.resolve_type = (fun t p ->
 		MacroApi.resolve_type = (fun t p ->
-			typing_timer ctx false (fun() -> Typeload.load_complex_type ctx false (t,p))
+			typing_timer ctx false (fun ctx -> Typeload.load_complex_type ctx false (t,p))
 		);
 		);
 		MacroApi.resolve_complex_type = (fun t ->
 		MacroApi.resolve_complex_type = (fun t ->
-			typing_timer ctx false (fun() ->
+			typing_timer ctx false (fun ctx ->
 				let rec load (t,_) =
 				let rec load (t,_) =
 					((match t with
 					((match t with
 					| CTPath ptp ->
 					| CTPath ptp ->
@@ -394,17 +396,17 @@ let make_macro_api ctx mctx p =
 			)
 			)
 		);
 		);
 		MacroApi.get_module = (fun s ->
 		MacroApi.get_module = (fun s ->
-			typing_timer ctx false (fun() ->
+			typing_timer ctx false (fun ctx ->
 				let path = parse_path s in
 				let path = parse_path s in
 				let m = List.map type_of_module_type (TypeloadModule.load_module ctx path p).m_types in
 				let m = List.map type_of_module_type (TypeloadModule.load_module ctx path p).m_types in
 				m
 				m
 			)
 			)
 		);
 		);
 		MacroApi.type_expr = (fun e ->
 		MacroApi.type_expr = (fun e ->
-			typing_timer ctx true (fun() -> type_expr ctx e WithType.value)
+			typing_timer ctx true (fun ctx -> type_expr ctx e WithType.value)
 		);
 		);
 		MacroApi.flush_context = (fun f ->
 		MacroApi.flush_context = (fun f ->
-			typing_timer ctx true f
+			typing_timer ctx true (fun _ -> f ())
 		);
 		);
 		MacroApi.get_local_type = (fun() ->
 		MacroApi.get_local_type = (fun() ->
 			match ctx.c.get_build_infos() with
 			match ctx.c.get_build_infos() with
@@ -500,7 +502,7 @@ let make_macro_api ctx mctx p =
 			end
 			end
 		);
 		);
 		MacroApi.module_dependency = (fun mpath file ->
 		MacroApi.module_dependency = (fun mpath file ->
-			let m = typing_timer ctx false (fun() ->
+			let m = typing_timer ctx false (fun ctx ->
 				let old_deps = ctx.m.curmod.m_extra.m_deps in
 				let old_deps = ctx.m.curmod.m_extra.m_deps in
 				let m = TypeloadModule.load_module ctx (parse_path mpath) p in
 				let m = TypeloadModule.load_module ctx (parse_path mpath) p in
 				ctx.m.curmod.m_extra.m_deps <- old_deps;
 				ctx.m.curmod.m_extra.m_deps <- old_deps;
@@ -512,7 +514,7 @@ let make_macro_api ctx mctx p =
 			ctx.m.curmod
 			ctx.m.curmod
 		);
 		);
 		MacroApi.cast_or_unify = (fun t e p ->
 		MacroApi.cast_or_unify = (fun t e p ->
-			typing_timer ctx true (fun () ->
+			typing_timer ctx true (fun ctx ->
 				try
 				try
 					ignore(AbstractCast.cast_or_unify_raise ctx t e p);
 					ignore(AbstractCast.cast_or_unify_raise ctx t e p);
 					true
 					true

+ 0 - 1
src/typing/typeload.ml

@@ -726,7 +726,6 @@ let rec type_type_param ctx host path p tp =
 	let c = mk_class ctx.m.curmod (fst path @ [snd path],n) (pos tp.tp_name) (pos tp.tp_name) in
 	let c = mk_class ctx.m.curmod (fst path @ [snd path],n) (pos tp.tp_name) (pos tp.tp_name) in
 	c.cl_params <- type_type_params ctx host c.cl_path p tp.tp_params;
 	c.cl_params <- type_type_params ctx host c.cl_path p tp.tp_params;
 	c.cl_meta <- tp.Ast.tp_meta;
 	c.cl_meta <- tp.Ast.tp_meta;
-	if host = TPHEnumConstructor then c.cl_meta <- (Meta.EnumConstructorParam,[],null_pos) :: c.cl_meta;
 	let ttp = mk_type_param c host None None in
 	let ttp = mk_type_param c host None None in
 	if ctx.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos tp.tp_name) then
 	if ctx.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos tp.tp_name) then
 		DisplayEmitter.display_type ctx ttp.ttp_type (pos tp.tp_name);
 		DisplayEmitter.display_type ctx ttp.ttp_type (pos tp.tp_name);

+ 12 - 7
src/typing/typeloadFields.ml

@@ -740,10 +740,11 @@ module TypeBinding = struct
 						display_error ctx.com ("Redefinition of variable " ^ cf.cf_name ^ " in subclass is not allowed. Previously declared at " ^ (s_type_path csup.cl_path) ) cf.cf_name_pos
 						display_error ctx.com ("Redefinition of variable " ^ cf.cf_name ^ " in subclass is not allowed. Previously declared at " ^ (s_type_path csup.cl_path) ) cf.cf_name_pos
 		end
 		end
 
 
-	let bind_var_expression ctx cctx fctx cf e =
+	let bind_var_expression ctx_f cctx fctx cf e =
 		let c = cctx.tclass in
 		let c = cctx.tclass in
 		let t = cf.cf_type in
 		let t = cf.cf_type in
 		let p = cf.cf_pos in
 		let p = cf.cf_pos in
+		let ctx = TyperManager.clone_for_expr ctx_f in
 		if (has_class_flag c CInterface) then unexpected_expression ctx.com fctx "Initialization on field of interface" (pos e);
 		if (has_class_flag c CInterface) then unexpected_expression ctx.com fctx "Initialization on field of interface" (pos e);
 		cf.cf_meta <- ((Meta.Value,[e],null_pos) :: cf.cf_meta);
 		cf.cf_meta <- ((Meta.Value,[e],null_pos) :: cf.cf_meta);
 		let check_cast e =
 		let check_cast e =
@@ -834,8 +835,9 @@ module TypeBinding = struct
 		| Some e ->
 		| Some e ->
 			bind_var_expression ctx cctx fctx cf e
 			bind_var_expression ctx cctx fctx cf e
 
 
-	let bind_method ctx cctx fctx cf t args ret e p =
+	let bind_method ctx_f cctx fctx cf t args ret e p =
 		let c = cctx.tclass in
 		let c = cctx.tclass in
+		let ctx = TyperManager.clone_for_expr ctx_f in
 		let bind r =
 		let bind r =
 			incr stats.s_methods_typed;
 			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 (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);
@@ -875,7 +877,7 @@ module TypeBinding = struct
 						if v.v_name <> "_" && has_mono v.v_type then warning ctx WTemp "Uninferred function argument, please add a type-hint" v.v_pos;
 						if v.v_name <> "_" && has_mono v.v_type then warning ctx WTemp "Uninferred function argument, please add a type-hint" v.v_pos;
 					) fargs; *)
 					) fargs; *)
 					let tf = {
 					let tf = {
-						tf_args = args#for_expr;
+						tf_args = args#for_expr ctx;
 						tf_type = ret;
 						tf_type = ret;
 						tf_expr = e;
 						tf_expr = e;
 					} in
 					} in
@@ -1192,7 +1194,7 @@ let setup_args_ret ctx cctx fctx name fd p =
 		in
 		in
 		if i = 0 then maybe_use_property_type cto (fun () -> match Lazy.force mk with MKSetter -> true | _ -> false) def else def()
 		if i = 0 then maybe_use_property_type cto (fun () -> match Lazy.force mk with MKSetter -> true | _ -> false) def else def()
 	in
 	in
-	let args = new FunctionArguments.function_arguments ctx type_arg is_extern fctx.is_display_field abstract_this fd.f_args in
+	let args = new FunctionArguments.function_arguments ctx.com type_arg is_extern fctx.is_display_field abstract_this fd.f_args in
 	args,ret
 	args,ret
 
 
 let create_method (ctx,cctx,fctx) c f fd p =
 let create_method (ctx,cctx,fctx) c f fd p =
@@ -1346,11 +1348,15 @@ let create_method (ctx,cctx,fctx) c f fd p =
 		if fctx.is_display_field then begin
 		if fctx.is_display_field then begin
 			delay ctx PTypeField (fun () ->
 			delay ctx PTypeField (fun () ->
 				(* We never enter type_function so we're missing out on the argument processing there. Let's do it here. *)
 				(* We never enter type_function so we're missing out on the argument processing there. Let's do it here. *)
-				ignore(args#for_expr)
+				let ctx = TyperManager.clone_for_expr ctx in
+				ignore(args#for_expr ctx)
 			);
 			);
 			check_field_display ctx fctx c cf;
 			check_field_display ctx fctx c cf;
 		end else
 		end else
-			delay ctx PTypeField (fun () -> args#verify_extern);
+			delay ctx PTypeField (fun () ->
+				let ctx = TyperManager.clone_for_expr ctx in
+				args#verify_extern ctx
+			);
 		if fd.f_expr <> None then begin
 		if fd.f_expr <> None then begin
 			if fctx.is_abstract then unexpected_expression ctx.com fctx "Abstract methods may not have an expression" p
 			if fctx.is_abstract then unexpected_expression ctx.com fctx "Abstract methods may not have an expression" p
 			else if not (fctx.is_inline || fctx.is_macro) then warning ctx WExternWithExpr "Extern non-inline function may not have an expression" p;
 			else if not (fctx.is_inline || fctx.is_macro) then warning ctx WExternWithExpr "Extern non-inline function may not have an expression" p;
@@ -1608,7 +1614,6 @@ let check_overloads ctx c =
 let finalize_class cctx =
 let finalize_class cctx =
 	(* push delays in reverse order so they will be run in correct order *)
 	(* push delays in reverse order so they will be run in correct order *)
 	List.iter (fun (ctx,r) ->
 	List.iter (fun (ctx,r) ->
-		init_class_done ctx;
 		(match r with
 		(match r with
 		| None -> ()
 		| None -> ()
 		| Some r -> delay ctx PTypeField (fun() -> ignore(lazy_type r)))
 		| Some r -> delay ctx PTypeField (fun() -> ignore(lazy_type r)))

+ 0 - 3
src/typing/typeloadFunction.ml

@@ -28,12 +28,9 @@ open Error
 open FunctionArguments
 open FunctionArguments
 
 
 let save_field_state ctx =
 let save_field_state ctx =
-	let old_e = ctx.e in
-	ctx.e <- TyperManager.create_ctx_e ();
 	let locals = ctx.f.locals in
 	let locals = ctx.f.locals in
 	(fun () ->
 	(fun () ->
 		ctx.f.locals <- locals;
 		ctx.f.locals <- locals;
-		ctx.e <- old_e;
 	)
 	)
 
 
 let type_function_params ctx fd host fname p =
 let type_function_params ctx fd host fname p =

+ 13 - 13
src/typing/typer.ml

@@ -1217,23 +1217,30 @@ and type_map_declaration ctx e1 el with_type p =
 	let el = (mk (TVar (v,Some enew)) t_dynamic p) :: (List.rev el) in
 	let el = (mk (TVar (v,Some enew)) t_dynamic p) :: (List.rev el) in
 	mk (TBlock el) tmap p
 	mk (TBlock el) tmap p
 
 
-and type_local_function ctx kind f with_type p =
+and type_local_function ctx_from kind f with_type p =
 	let name,inline = match kind with FKNamed (name,inline) -> Some name,inline | _ -> None,false in
 	let name,inline = match kind with FKNamed (name,inline) -> Some name,inline | _ -> None,false in
-	let params = TypeloadFunction.type_function_params ctx f TPHLocal (match name with None -> "localfun" | Some (n,_) -> n) p in
+	let params = TypeloadFunction.type_function_params ctx_from f TPHLocal (match name with None -> "localfun" | Some (n,_) -> n) p in
 	if params <> [] then begin
 	if params <> [] then begin
-		if name = None then display_error ctx.com "Type parameters not supported in unnamed local functions" p;
+		if name = None then display_error ctx_from.com "Type parameters not supported in unnamed local functions" p;
 		if with_type <> WithType.NoValue then raise_typing_error "Type parameters are not supported for rvalue functions" p
 		if with_type <> WithType.NoValue then raise_typing_error "Type parameters are not supported for rvalue functions" p
 	end;
 	end;
 	let v,pname = (match name with
 	let v,pname = (match name with
 		| None -> None,p
 		| None -> None,p
 		| Some (v,pn) -> Some v,pn
 		| Some (v,pn) -> Some v,pn
 	) in
 	) in
-	let old_tp,old_in_loop = ctx.type_params,ctx.e.in_loop in
+	let curfun = match ctx_from.e.curfun with
+		| FunStatic -> FunStatic
+		| FunMemberAbstract
+		| FunMemberAbstractLocal -> FunMemberAbstractLocal
+		| _ -> FunMemberClassLocal
+	in
+	let ctx = TyperManager.clone_for_expr ctx_from in
+	let old_tp = ctx.type_params in
 	ctx.type_params <- params @ ctx.type_params;
 	ctx.type_params <- params @ ctx.type_params;
 	if not inline then ctx.e.in_loop <- false;
 	if not inline then ctx.e.in_loop <- false;
 	let rt = Typeload.load_type_hint ctx p f.f_type in
 	let rt = Typeload.load_type_hint ctx p f.f_type in
 	let type_arg _ opt t p = Typeload.load_type_hint ~opt ctx p t in
 	let type_arg _ opt t p = Typeload.load_type_hint ~opt ctx p t in
-	let args = new FunctionArguments.function_arguments ctx type_arg false ctx.f.in_display None f.f_args in
+	let args = new FunctionArguments.function_arguments ctx.com type_arg false ctx.f.in_display None f.f_args in
 	let targs = args#for_type in
 	let targs = args#for_type in
 	let maybe_unify_arg t1 t2 =
 	let maybe_unify_arg t1 t2 =
 		match follow t1 with
 		match follow t1 with
@@ -1331,17 +1338,10 @@ and type_local_function ctx kind f with_type p =
 			if params <> [] then v.v_extra <- Some (var_extra params None);
 			if params <> [] then v.v_extra <- Some (var_extra params None);
 			Some v
 			Some v
 	) in
 	) in
-	let curfun = match ctx.e.curfun with
-		| FunStatic -> FunStatic
-		| FunMemberAbstract
-		| FunMemberAbstractLocal -> FunMemberAbstractLocal
-		| _ -> FunMemberClassLocal
-	in
 	let e = TypeloadFunction.type_function ctx args rt curfun f.f_expr ctx.f.in_display p in
 	let e = TypeloadFunction.type_function ctx args rt curfun f.f_expr ctx.f.in_display p in
 	ctx.type_params <- old_tp;
 	ctx.type_params <- old_tp;
-	ctx.e.in_loop <- old_in_loop;
 	let tf = {
 	let tf = {
-		tf_args = args#for_expr;
+		tf_args = args#for_expr ctx;
 		tf_type = rt;
 		tf_type = rt;
 		tf_expr = e;
 		tf_expr = e;
 	} in
 	} in

+ 0 - 1
src/typing/typerDisplay.ml

@@ -583,7 +583,6 @@ let handle_display ctx e_ast dk mode with_type =
 			raise_toplevel ctx dk with_type (s_type_path path,p)
 			raise_toplevel ctx dk with_type (s_type_path path,p)
 	| DisplayException(DisplayFields ({fkind = CRTypeHint} as r)) when (match fst e_ast with ENew _ -> true | _ -> false) ->
 	| DisplayException(DisplayFields ({fkind = CRTypeHint} as r)) when (match fst e_ast with ENew _ -> true | _ -> false) ->
 		let timer = Timer.timer ["display";"toplevel";"filter ctors"] in
 		let timer = Timer.timer ["display";"toplevel";"filter ctors"] in
-		ctx.pass <- PBuildClass;
 		let l = List.filter (fun item ->
 		let l = List.filter (fun item ->
 			let is_private_to_current_module mt =
 			let is_private_to_current_module mt =
 				(* Remove the _Module nonsense from the package *)
 				(* Remove the _Module nonsense from the package *)

+ 3 - 0
tests/misc/projects/Issue11538/M.hx

@@ -0,0 +1,3 @@
+class M {
+	static public var x:Float;
+}

+ 25 - 0
tests/misc/projects/Issue11538/Main.hx

@@ -0,0 +1,25 @@
+import haxe.macro.Context;
+import haxe.macro.Expr;
+
+using haxe.macro.Tools;
+
+#if !macro
+@:build(Main.build())
+#end
+class Main {
+	#if macro
+	static function build():Array<Field> {
+		var t = Context.typeof(macro M.x);
+		var field = (macro class X {
+			static public var type = $v{t.toString()};
+		}).fields[0];
+		return [field];
+	}
+	#end
+}
+
+function main() {
+	#if !macro
+	trace(Main.type);
+	#end
+}

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

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

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

@@ -0,0 +1 @@
+Main.hx:23: Float