Skip to content

Commit

Permalink
Make ctx.pass immutable (#11538)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Simn committed Feb 5, 2024
1 parent eb37cee commit 3f13b75
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 76 deletions.
7 changes: 0 additions & 7 deletions src-json/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,13 +295,6 @@
"targets": ["TAbstract"],
"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",
"metadata": ":event",
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/gencommon/normalize.ml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ open Gencommon

let rec filter_param (stack:t list) t =
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
| TMono r ->
(match r.tm_type with
Expand Down
39 changes: 17 additions & 22 deletions src/context/typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ and typer = {
mutable m : typer_module;
c : typer_class;
f : typer_field;
mutable e : typer_expr;
mutable pass : typer_pass;
e : typer_expr;
pass : typer_pass;
mutable type_params : type_params;
mutable allow_inline : bool;
mutable allow_transform : bool;
Expand All @@ -183,7 +183,7 @@ and monomorphs = {
}

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;
g = g;
t = com.basic;
Expand All @@ -192,8 +192,8 @@ module TyperManager = struct
f = f;
e = e;
pass = pass;
allow_inline = true;
allow_transform = true;
allow_inline;
allow_transform;
type_params = params;
memory_marker = memory_marker;
}
Expand Down Expand Up @@ -244,42 +244,46 @@ module TyperManager = struct
let c = create_ctx_c null_class in
let f = create_ctx_f null_field 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 c = create_ctx_c c in
let f = create_ctx_f null_field 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
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 c = create_ctx_c null_class in
let f = create_ctx_f null_field 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 c = create_ctx_c null_class in
let f = create_ctx_f null_field 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 c = create_ctx_c null_class in
let f = create_ctx_f null_field 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 f = create_ctx_f cf 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 f = create_ctx_f null_field 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

type field_host =
Expand Down Expand Up @@ -559,12 +563,8 @@ let rec flush_pass ctx p where =

let make_pass ctx f = f

let init_class_done ctx =
ctx.pass <- PConnectField

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 r = ref (lazy_available t_dynamic) in
Expand Down Expand Up @@ -909,11 +909,6 @@ let debug com (path : string list) str =
if List.exists (Ast.match_path false path) debug_paths then emit();
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 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
Expand Down
16 changes: 8 additions & 8 deletions src/typing/functionArguments.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ open Type
open Typecore
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 *)
(* delay ctx PTypeField (fun() ->
if ExtType.is_void (follow t) then
error "Arguments of type Void are not allowed" p
); *)
if opt then
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
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

let type_function_arg_value ctx t c do_display =
Expand All @@ -38,7 +38,7 @@ let type_function_arg_value ctx t c do_display =
loop e

class function_arguments
(ctx : typer)
(com : Common.context)
(type_arg : int -> bool -> type_hint option -> pos -> Type.t)
(is_extern : bool)
(do_display : bool)
Expand All @@ -48,7 +48,7 @@ class function_arguments
let with_default =
let l = List.mapi (fun i ((name,pn),opt,_,t,eo) ->
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)
) syntax in
let l = match abstract_this with
Expand Down Expand Up @@ -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
an argument should be displayed. *)
method for_expr = match expr_repr with
method for_expr ctx = match expr_repr with
| Some l ->
l
| None ->
Expand Down Expand Up @@ -116,7 +116,7 @@ object(self)
l

(* 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
| syntax,(name,_,t) :: typed when is_abstract_this ->
loop false syntax typed
Expand All @@ -135,5 +135,5 @@ object(self)
method bring_into_context ctx =
List.iter (fun (v,_) ->
ctx.f.locals <- PMap.add v.v_name v ctx.f.locals
) self#for_expr
) (self#for_expr ctx)
end
28 changes: 15 additions & 13 deletions src/typing/macroContext.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,28 @@ let macro_timer com l =

let typing_timer ctx need_type f =
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
(*
disable resumable errors... unless we are in display mode (we want to reach point of completion)
*)
(* 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 });

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: ? *));
end;
TyperManager.clone_for_expr ctx
end else
ctx
in
let exit() =
t();
ctx.com.error_ext <- old;
ctx.pass <- oldp;
ctx.f.locals <- oldlocals;
restore_report_mode ();
in
try
let r = f() in
let r = f ctx in
exit();
r
with Error err ->
Expand Down Expand Up @@ -322,7 +324,7 @@ let make_macro_api ctx mctx p =
{
com_api with
MacroApi.get_type = (fun s ->
typing_timer ctx false (fun() ->
typing_timer ctx false (fun ctx ->
let path = parse_path s in
let tp = match List.rev (fst path) with
| s :: sl when String.length s > 0 && (match s.[0] with 'A'..'Z' -> true | _ -> false) ->
Expand All @@ -338,10 +340,10 @@ let make_macro_api ctx mctx 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 ->
typing_timer ctx false (fun() ->
typing_timer ctx false (fun ctx ->
let rec load (t,_) =
((match t with
| CTPath ptp ->
Expand Down Expand Up @@ -394,17 +396,17 @@ let make_macro_api ctx mctx p =
)
);
MacroApi.get_module = (fun s ->
typing_timer ctx false (fun() ->
typing_timer ctx false (fun ctx ->
let path = parse_path s in
let m = List.map type_of_module_type (TypeloadModule.load_module ctx path p).m_types in
m
)
);
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 ->
typing_timer ctx true f
typing_timer ctx true (fun _ -> f ())
);
MacroApi.get_local_type = (fun() ->
match ctx.c.get_build_infos() with
Expand Down Expand Up @@ -500,7 +502,7 @@ let make_macro_api ctx mctx p =
end
);
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 m = TypeloadModule.load_module ctx (parse_path mpath) p in
ctx.m.curmod.m_extra.m_deps <- old_deps;
Expand All @@ -512,7 +514,7 @@ let make_macro_api ctx mctx p =
ctx.m.curmod
);
MacroApi.cast_or_unify = (fun t e p ->
typing_timer ctx true (fun () ->
typing_timer ctx true (fun ctx ->
try
ignore(AbstractCast.cast_or_unify_raise ctx t e p);
true
Expand Down
1 change: 0 additions & 1 deletion src/typing/typeload.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
c.cl_params <- type_type_params ctx host c.cl_path p tp.tp_params;
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
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);
Expand Down
19 changes: 12 additions & 7 deletions src/typing/typeloadFields.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
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 t = cf.cf_type 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);
cf.cf_meta <- ((Meta.Value,[e],null_pos) :: cf.cf_meta);
let check_cast e =
Expand Down Expand Up @@ -834,8 +835,9 @@ module TypeBinding = struct
| Some 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 ctx = TyperManager.clone_for_expr ctx_f in
let bind r =
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);
Expand Down Expand Up @@ -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;
) fargs; *)
let tf = {
tf_args = args#for_expr;
tf_args = args#for_expr ctx;
tf_type = ret;
tf_expr = e;
} in
Expand Down Expand Up @@ -1192,7 +1194,7 @@ let setup_args_ret ctx cctx fctx name fd p =
in
if i = 0 then maybe_use_property_type cto (fun () -> match Lazy.force mk with MKSetter -> true | _ -> false) def else def()
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

let create_method (ctx,cctx,fctx) c f fd p =
Expand Down Expand Up @@ -1346,11 +1348,15 @@ let create_method (ctx,cctx,fctx) c f fd p =
if fctx.is_display_field then begin
delay ctx PTypeField (fun () ->
(* 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;
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 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;
Expand Down Expand Up @@ -1608,7 +1614,6 @@ let check_overloads ctx c =
let finalize_class cctx =
(* push delays in reverse order so they will be run in correct order *)
List.iter (fun (ctx,r) ->
init_class_done ctx;
(match r with
| None -> ()
| Some r -> delay ctx PTypeField (fun() -> ignore(lazy_type r)))
Expand Down
3 changes: 0 additions & 3 deletions src/typing/typeloadFunction.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@ open Error
open FunctionArguments

let save_field_state ctx =
let old_e = ctx.e in
ctx.e <- TyperManager.create_ctx_e ();
let locals = ctx.f.locals in
(fun () ->
ctx.f.locals <- locals;
ctx.e <- old_e;
)

let type_function_params ctx fd host fname p =
Expand Down

0 comments on commit 3f13b75

Please sign in to comment.