From 2f56f2cb21bb13b8c4e8b73600dcc8873e8c29fb Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sat, 3 Feb 2024 18:01:58 +0100 Subject: [PATCH 01/13] don't recurse --- std/haxe/macro/Compiler.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/haxe/macro/Compiler.hx b/std/haxe/macro/Compiler.hx index 1ba1ed88e6f..c1996cfddaf 100644 --- a/std/haxe/macro/Compiler.hx +++ b/std/haxe/macro/Compiler.hx @@ -379,7 +379,7 @@ class Compiler { public static function addMetadata(meta:String, className:String, ?field:String, ?isStatic:Bool) { var pathFilter = field == null ? className : '$className.$field'; - addGlobalMetadata(pathFilter, meta, true, field == null, field != null); + addGlobalMetadata(pathFilter, meta, false, field == null, field != null); } /** From 23c865f56c92a7541fb70da927c7abfedfba9070 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 21:40:15 +0100 Subject: [PATCH 02/13] [tests] update test for #3500 --- tests/misc/projects/Issue3500/Main.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/misc/projects/Issue3500/Main.hx b/tests/misc/projects/Issue3500/Main.hx index 4b9e8577129..ba8e6f064b3 100644 --- a/tests/misc/projects/Issue3500/Main.hx +++ b/tests/misc/projects/Issue3500/Main.hx @@ -9,7 +9,7 @@ class Main { var t = haxe.macro.Context.getType("A"); switch (t) { case TAbstract(a, _): - var hasTestMeta = Lambda.exists(a.get().impl.get().meta.get(), function(m) return m.name == ":test"); + var hasTestMeta = Lambda.exists(a.get().meta.get(), function(m) return m.name == ":test"); if (!hasTestMeta) { fail("Abstract implementation class has no @:test metadata"); } From 769917217358d0b9d54e0ef9bd78aa3171b1019e Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 21:43:02 +0100 Subject: [PATCH 03/13] [typer] move abstract -> impl meta inheritance to after addGlobalMetadata --- src/typing/typeloadModule.ml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/typing/typeloadModule.ml b/src/typing/typeloadModule.ml index 35889603d3a..701dd8913ee 100644 --- a/src/typing/typeloadModule.ml +++ b/src/typing/typeloadModule.ml @@ -219,12 +219,6 @@ module ModuleLevel = struct let acc = make_decl acc (EClass { d_name = (fst d.d_name) ^ "_Impl_",snd d.d_name; d_flags = [HPrivate]; d_data = fields; d_doc = None; d_params = []; d_meta = !meta },p) in (match !decls with | (TClassDecl c,_) :: _ -> - List.iter (fun m -> match m with - | ((Meta.Using | Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.HlNative | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpGlobal | Meta.PublicFields),_,_) -> - c.cl_meta <- m :: c.cl_meta; - | _ -> - () - ) a.a_meta; a.a_impl <- Some c; c.cl_kind <- KAbstractImpl a; add_class_flag c CFinal; @@ -574,6 +568,14 @@ module TypeLevel = struct if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then DisplayEmitter.display_module_type ctx_m (TAbstractDecl a) (pos d.d_name); TypeloadCheck.check_global_metadata ctx_m a.a_meta (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None; + Option.may (fun c -> + List.iter (fun m -> match m with + | ((Meta.Using | Meta.Build | Meta.CoreApi | Meta.Allow | Meta.Access | Meta.Enum | Meta.Dce | Meta.Native | Meta.HlNative | Meta.JsRequire | Meta.PythonImport | Meta.Expose | Meta.Deprecated | Meta.PhpGlobal | Meta.PublicFields),_,_) -> + c.cl_meta <- m :: c.cl_meta; + | _ -> + () + ) a.a_meta; + ) a.a_impl; let ctx_a = TyperManager.clone_for_abstract ctx_m a in let is_type = ref false in let load_type t from = From 75c573c588caf81f0f2d5f4a07485e4a54afd9b7 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 22:15:31 +0100 Subject: [PATCH 04/13] [tests] remove test with pretty errors that brings nothing but pain --- .../user-defined-meta-json-pretty-fail.hxml | 4 ---- .../user-defined-meta-json-pretty-fail.hxml.stderr | 12 ------------ 2 files changed, 16 deletions(-) delete mode 100644 tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml delete mode 100644 tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr diff --git a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml b/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml deleted file mode 100644 index 68353040073..00000000000 --- a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml +++ /dev/null @@ -1,4 +0,0 @@ -user-defined-meta-json-fail.hxml --D message.reporting=pretty --D message.no-color - diff --git a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr b/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr deleted file mode 100644 index 6c235767c49..00000000000 --- a/tests/misc/projects/Issue10844/user-defined-meta-json-pretty-fail.hxml.stderr +++ /dev/null @@ -1,12 +0,0 @@ -[ERROR] --macro haxe.macro.Compiler.registerMetadataDescriptionFile('meta.jsno', 'myapp') - - | Uncaught exception Could not read file meta.jsno - - -> $$normPath(::std::)/haxe/macro/Compiler.hx:390: characters 11-39 - - 390 | var f = sys.io.File.getContent(path); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Called from here - - | Called from here - From 48b51891485048c76dee9e6566e54c54d6eac814 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 22:15:50 +0100 Subject: [PATCH 05/13] [std] deprecate Compiler.addMetadata again --- std/haxe/macro/Compiler.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/std/haxe/macro/Compiler.hx b/std/haxe/macro/Compiler.hx index c1996cfddaf..854082e4e31 100644 --- a/std/haxe/macro/Compiler.hx +++ b/std/haxe/macro/Compiler.hx @@ -377,6 +377,7 @@ class Compiler { #end } + @:deprecated public static function addMetadata(meta:String, className:String, ?field:String, ?isStatic:Bool) { var pathFilter = field == null ? className : '$className.$field'; addGlobalMetadata(pathFilter, meta, false, field == null, field != null); From 2cecaff3f0492129cbfa920dcad190c527b29f52 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 22:16:34 +0100 Subject: [PATCH 06/13] [tests] misc tests: ignore position changes for std modules Closes #11539 --- tests/misc/src/Main.hx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 4f387cc95d1..63607bdd21a 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -151,6 +151,9 @@ class Main { .filter(s -> 0 != s.indexOf('Picked up JAVA_TOOL_OPTIONS:')) .join('\n'); + content = hideStdPositions(content); + expected = hideStdPositions(expected); + if (StringTools.startsWith(content, '{"jsonrpc":')) { try { content = haxe.Json.stringify(haxe.Json.parse(content).result.result); @@ -178,6 +181,15 @@ class Main { return true; } + static function hideStdPositions(content:String):String { + var std = Path.removeTrailingSlashes(getStd()); + var regex = new EReg(std + '([a-z/]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); + + return content.split("\n") + .map(line -> regex.replace(line, "$1:???:")) + .join("\n"); + } + static macro function getStd() { var std = Compiler.getConfiguration().stdPath; return macro $v{std.shift()}; From 8a255c841b33b602437f9aa5db57cb7c5a26c46a Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sat, 3 Feb 2024 22:27:02 +0100 Subject: [PATCH 07/13] [tests] improve std position hiding a bit --- tests/misc/src/Main.hx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 63607bdd21a..006fcfad174 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -151,15 +151,15 @@ class Main { .filter(s -> 0 != s.indexOf('Picked up JAVA_TOOL_OPTIONS:')) .join('\n'); - content = hideStdPositions(content); - expected = hideStdPositions(expected); - if (StringTools.startsWith(content, '{"jsonrpc":')) { try { content = haxe.Json.stringify(haxe.Json.parse(content).result.result); // Reorder fields from expected too expected = haxe.Json.stringify(haxe.Json.parse(expected)); } catch (_) {} + } else { + content = hideStdPositions(content); + expected = hideStdPositions(expected); } if (content != expected) { @@ -182,8 +182,7 @@ class Main { } static function hideStdPositions(content:String):String { - var std = Path.removeTrailingSlashes(getStd()); - var regex = new EReg(std + '([a-z/]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); + var regex = new EReg(getStd() + '([a-z/]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); return content.split("\n") .map(line -> regex.replace(line, "$1:???:")) From 732be46cad4ac7edef88886d3612a71c726b54a7 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sun, 4 Feb 2024 08:10:27 +0100 Subject: [PATCH 08/13] remove all "Something went wrong" errors --- src/generators/genjvm.ml | 2 +- src/generators/genshared.ml | 9 +++++---- src/macro/eval/evalEmitter.ml | 4 ++-- src/macro/eval/evalExceptions.ml | 6 +++--- src/macro/eval/evalJit.ml | 2 +- src/typing/matcher/texprConverter.ml | 2 +- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/generators/genjvm.ml b/src/generators/genjvm.ml index ca7cbfcb533..ea90c8c5868 100644 --- a/src/generators/genjvm.ml +++ b/src/generators/genjvm.ml @@ -1675,7 +1675,7 @@ class texpr_to_jvm info.super_call_fields <- tl; hd | _ -> - Error.raise_typing_error "Something went wrong" e1.epos + Error.raise_typing_error "Could not find field information for super call, please report this" e1.epos in let kind = get_construction_mode c cf in begin match kind with diff --git a/src/generators/genshared.ml b/src/generators/genshared.ml index aa6c7bab126..9aa67cea7b3 100644 --- a/src/generators/genshared.ml +++ b/src/generators/genshared.ml @@ -128,14 +128,15 @@ object(self) | None -> die "" __LOC__ | Some(c,_) -> c,cf in - let rec promote_this_before_super c cf = match self#get_field_info cf.cf_meta with - | None -> failwith "Something went wrong" + let rec promote_this_before_super c cf p = match self#get_field_info cf.cf_meta with + | None -> + Error.raise_typing_error (Printf.sprintf "Could not determine field information for %s in a this-before-super case, please report this" cf.cf_name) p | Some info -> if not info.has_this_before_super then begin make_haxe cf; (* print_endline (Printf.sprintf "promoted this_before_super to %s.new : %s" (s_type_path c.cl_path) (s_type (print_context()) cf.cf_type)); *) info.has_this_before_super <- true; - List.iter (fun (c,cf) -> promote_this_before_super c cf) info.super_call_fields + List.iter (fun (c,cf) -> promote_this_before_super c cf p) info.super_call_fields end in let rec loop e = @@ -153,7 +154,7 @@ object(self) (* print_endline (Printf.sprintf "inferred this_before_super on %s.new : %s" (s_type_path c.cl_path) (s_type (print_context()) cf.cf_type)); *) end; let c,cf = find_super_ctor el in - if !this_before_super then promote_this_before_super c cf; + if !this_before_super then promote_this_before_super c cf e.epos; DynArray.add super_call_fields (c,cf); | _ -> Type.iter loop e diff --git a/src/macro/eval/evalEmitter.ml b/src/macro/eval/evalEmitter.ml index 56de9326e61..7663674aac7 100644 --- a/src/macro/eval/evalEmitter.ml +++ b/src/macro/eval/evalEmitter.ml @@ -754,8 +754,8 @@ let process_arguments fl vl env = loop fl [] | [],[] -> () - | _ -> - exc_string "Something went wrong" + | l1,l2 -> + exc_string (Printf.sprintf "Bad number of arguments: %i vs. %i" (List.length l1) (List.length l2)) in loop fl vl [@@inline] diff --git a/src/macro/eval/evalExceptions.ml b/src/macro/eval/evalExceptions.ml index f1c146d98d6..b3954e20692 100644 --- a/src/macro/eval/evalExceptions.ml +++ b/src/macro/eval/evalExceptions.ml @@ -137,7 +137,7 @@ let catch_exceptions ctx ?(final=(fun() -> ())) f p = in (Error.Custom (value_string v1), v2) end else - Error.raise_typing_error "Something went wrong" null_pos + Error.raise_typing_error (Printf.sprintf "Unexpected value where haxe.macro.Error was expected: %s" (s_value 0 v).sstring) null_pos ) (EvalArray.to_list sub) | _ -> [] in @@ -165,8 +165,8 @@ let catch_exceptions ctx ?(final=(fun() -> ())) f p = | [] -> Error.raise_msg s.sstring p | _ -> Error.raise_error (Error.make_error ~sub:(List.map (fun (msg,p) -> Error.make_error msg p) stack) (Error.Custom s.sstring) p) ); - | _ -> - Error.raise_typing_error "Something went wrong" null_pos + | v -> + Error.raise_typing_error (Printf.sprintf "Invalid exception value where string was expected: %s" (s_value 0 v).sstring) null_pos end else begin (* Careful: We have to get the message before resetting the context because toString() might access it. *) let stack = match eval_stack with diff --git a/src/macro/eval/evalJit.ml b/src/macro/eval/evalJit.ml index d2c21a539a1..89c428641ce 100644 --- a/src/macro/eval/evalJit.ml +++ b/src/macro/eval/evalJit.ml @@ -235,7 +235,7 @@ and jit_expr jit return e = List.iter (fun var -> ignore(get_capture_slot jit var)) jit_closure.captures_outside_scope; let captures = ExtList.List.filter_map (fun (i,vid,declared) -> if declared then None - else Some (i,fst (try Hashtbl.find jit.captures vid with Not_found -> Error.raise_typing_error "Something went wrong" e.epos)) + else Some (i,fst (try Hashtbl.find jit.captures vid with Not_found -> Error.raise_typing_error (Printf.sprintf "Could not find capture variable %i" vid) e.epos)) ) captures in let mapping = Array.of_list captures in emit_closure ctx mapping eci hasret exec fl diff --git a/src/typing/matcher/texprConverter.ml b/src/typing/matcher/texprConverter.ml index 87f92657803..dfe269d63f9 100644 --- a/src/typing/matcher/texprConverter.ml +++ b/src/typing/matcher/texprConverter.ml @@ -25,7 +25,7 @@ let constructor_to_texpr ctx con = | ConArray i -> make_int ctx.com.basic i p | ConTypeExpr mt -> TyperBase.type_module_type ctx mt p | ConStatic(c,cf) -> make_static_field c cf p - | ConFields _ -> raise_typing_error "Something went wrong" p + | ConFields _ -> raise_typing_error "Unexpected matching on ConFields, please report this" p let s_subject v_lookup s e = let rec loop top s e = match e.eexpr with From 782c520c556a9f2f8769da448f6ad7e2c48a5ceb Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sun, 4 Feb 2024 08:34:25 +0100 Subject: [PATCH 09/13] [tests] well ofc there's windows too.. --- tests/misc/src/Main.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 006fcfad174..67684712571 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -182,7 +182,7 @@ class Main { } static function hideStdPositions(content:String):String { - var regex = new EReg(getStd() + '([a-z/]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); + var regex = new EReg(getStd() + '([a-z/\\\\]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); return content.split("\n") .map(line -> regex.replace(line, "$1:???:")) From 61fae054de31a5f04070263d2caa5859f1248d04 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Sun, 4 Feb 2024 09:21:41 +0100 Subject: [PATCH 10/13] [tests] need to escape those slashes on windows --- tests/misc/src/Main.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 67684712571..7e05e1da364 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -182,7 +182,7 @@ class Main { } static function hideStdPositions(content:String):String { - var regex = new EReg(getStd() + '([a-z/\\\\]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); + var regex = new EReg(StringTools.replace(getStd(), '\\', '(?:\\\\|/)') + '([a-z/\\\\]+\\.hx):[0-9]+:( characters? [0-9]+(-[0-9]+)( :)?)', 'i'); return content.split("\n") .map(line -> regex.replace(line, "$1:???:")) From c55da75267dbe1c6011432a1b30644da2b7ba79d Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sun, 4 Feb 2024 13:44:36 +0100 Subject: [PATCH 11/13] [typer] don't consider @:structInit + @:from when inferring closes #11535 --- src/typing/matcher/exprToPattern.ml | 2 +- src/typing/typer.ml | 30 +++++++++------------ src/typing/typerBase.ml | 8 ++++-- tests/unit/src/unit/issues/Issue11535.hx | 34 ++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 tests/unit/src/unit/issues/Issue11535.hx diff --git a/src/typing/matcher/exprToPattern.ml b/src/typing/matcher/exprToPattern.ml index 3db86b92e1a..4ca68a1c4a2 100644 --- a/src/typing/matcher/exprToPattern.ml +++ b/src/typing/matcher/exprToPattern.ml @@ -315,7 +315,7 @@ let rec make pctx toplevel t e = PatConstructor(con_array (List.length patterns) (pos e),patterns) | TAbstract(a,tl) as t when not (List.exists (fun t' -> shallow_eq t t') seen) -> begin match TyperBase.get_abstract_froms ctx a tl with - | [t2] -> pattern (t :: seen) t2 + | [(_,t2)] -> pattern (t :: seen) t2 | _ -> fail() end | _ -> diff --git a/src/typing/typer.ml b/src/typing/typer.ml index 13aca40a8de..57778ec4f16 100644 --- a/src/typing/typer.ml +++ b/src/typing/typer.ml @@ -96,7 +96,7 @@ let maybe_type_against_enum ctx f with_type iscall p = false,a.a_path,fields,TAbstractDecl a | TAbstract (a,pl) when not (Meta.has Meta.CoreType a.a_meta) -> begin match get_abstract_froms ctx a pl with - | [t2] -> + | [(_,t2)] -> if (List.exists (shallow_eq t) stack) then raise Exit; loop (t :: stack) t2 | _ -> raise Exit @@ -782,14 +782,15 @@ and type_object_decl ctx fl with_type p = let dynamic_parameter = ref None in let a = (match with_type with | WithType.WithType(t,_) -> - let rec loop seen t = + let rec loop had_cast seen t = match follow t with - | TAnon a -> ODKWithStructure a + | TAnon a -> + ODKWithStructure a | TAbstract (a,pl) as t when not (Meta.has Meta.CoreType a.a_meta) && not (List.exists (fun t' -> shallow_eq t t') seen) -> let froms = get_abstract_froms ctx a pl in - let fold = fun acc t' -> match loop (t :: seen) t' with ODKPlain -> acc | t -> t :: acc in + let fold = fun acc (fk,t') -> match loop (fk = FromField) (t :: seen) t' with ODKPlain -> acc | t -> t :: acc in begin match List.fold_left fold [] froms with | [] -> ODKPlain (* If the abstract has no casts in the first place, we can assume plain typing (issue #10730) *) | [t] -> t @@ -801,12 +802,12 @@ and type_object_decl ctx fl with_type p = a_status = ref Closed; a_fields = PMap.empty; } - | TInst(c,tl) when Meta.has Meta.StructInit c.cl_meta -> + | TInst(c,tl) when not had_cast && Meta.has Meta.StructInit c.cl_meta -> ODKWithClass(c,tl) | _ -> ODKPlain in - loop [] t + loop false [] t | _ -> ODKPlain ) in @@ -1296,14 +1297,14 @@ and type_local_function ctx kind f with_type p = maybe_unify_ret tr | TAbstract(a,tl) -> begin match get_abstract_froms ctx a tl with - | [t2] -> + | [(_,t2)] -> if not (List.exists (shallow_eq t) stack) then loop (t :: stack) t2 | l -> (* For cases like nested EitherType, we want a flat list of all possible candidates. This might be controversial because those could be considered transitive casts, but it's unclear if that's a bad thing for this kind of inference (issue #10982). *) let rec loop stack acc l = match l with - | t :: l -> + | (_,t) :: l -> begin match follow t with | TAbstract(a,tl) as t when not (List.exists (shallow_eq t) stack) -> loop (t :: stack) acc (l @ get_abstract_froms ctx a tl) @@ -1398,15 +1399,10 @@ and type_array_decl ctx el with_type p = with Not_found -> None) | TAbstract (a,pl) as t when not (List.exists (fun t' -> shallow_eq t t') seen) -> - let types = - List.fold_left - (fun acc t' -> match loop (t :: seen) t' with - | None -> acc - | Some t -> t :: acc - ) - [] - (get_abstract_froms ctx a pl) - in + let types = List.fold_left (fun acc (_,t') -> match loop (t :: seen) t' with + | None -> acc + | Some t -> t :: acc + ) [] (get_abstract_froms ctx a pl) in (match types with | [t] -> Some t | _ -> None) diff --git a/src/typing/typerBase.ml b/src/typing/typerBase.ml index 829ad9fa104..fa7bdefb8e2 100644 --- a/src/typing/typerBase.ml +++ b/src/typing/typerBase.ml @@ -330,8 +330,12 @@ let unify_static_extension ctx e t p = e end +type from_kind = + | FromType + | FromField + let get_abstract_froms ctx a pl = - let l = List.map (apply_params a.a_params pl) a.a_from in + let l = List.map (fun t -> FromType,apply_params a.a_params pl t) a.a_from in List.fold_left (fun acc (t,f) -> (* We never want to use the @:from we're currently in because that's recursive (see #10604) *) if f == ctx.f.curfield then @@ -342,7 +346,7 @@ let get_abstract_froms ctx a pl = | TFun ([_,_,v],t) -> (try ignore(type_eq EqStrict t (TAbstract(a,List.map duplicate pl))); (* unify fields monomorphs *) - v :: acc + (FromField,v) :: acc with Unify_error _ -> acc) | _ -> diff --git a/tests/unit/src/unit/issues/Issue11535.hx b/tests/unit/src/unit/issues/Issue11535.hx new file mode 100644 index 00000000000..2ce98ab3245 --- /dev/null +++ b/tests/unit/src/unit/issues/Issue11535.hx @@ -0,0 +1,34 @@ +package unit.issues; + +@:structInit +private class BarImpl { + public function new() {} +} + +@:structInit +private class FooImpl { + public var x:Int; + + public function new(x:Int) { + this.x = x; + } +} + +@:forward +private abstract Foo(FooImpl) from FooImpl to FooImpl { + public function new(x:Int) { + this = new FooImpl(x); + } + + @:from + static public function fromVec4(v:BarImpl):Foo { + return new Foo(1); + } +} + +class Issue11535 extends Test { + function test() { + var v:Foo = {x: 2}; + eq(2, v.x); + } +} From eb37ceeb865d8af8f9a9cb5dadf22bb2153348e8 Mon Sep 17 00:00:00 2001 From: Rudy Ges Date: Mon, 5 Feb 2024 06:54:20 +0100 Subject: [PATCH 12/13] Skip abstract impl classes when applying addGlobalMetadata (#11546) * [typer] don't add meta to abstract impl through addGlobalMetadata * [tests] add test for #11545 --- src/typing/typeloadModule.ml | 5 +++- tests/misc/projects/Issue11545/Macro.hx | 30 +++++++++++++++++++ tests/misc/projects/Issue11545/Main.hx | 12 ++++++++ tests/misc/projects/Issue11545/compile.hxml | 2 ++ .../projects/Issue11545/compile.hxml.stdout | 3 ++ 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/misc/projects/Issue11545/Macro.hx create mode 100644 tests/misc/projects/Issue11545/Main.hx create mode 100644 tests/misc/projects/Issue11545/compile.hxml create mode 100644 tests/misc/projects/Issue11545/compile.hxml.stdout diff --git a/src/typing/typeloadModule.ml b/src/typing/typeloadModule.ml index 701dd8913ee..cc8a2c0d1a9 100644 --- a/src/typing/typeloadModule.ml +++ b/src/typing/typeloadModule.ml @@ -377,7 +377,10 @@ module TypeLevel = struct let init_class ctx_m c d p = if ctx_m.m.is_display_file && DisplayPosition.display_position#enclosed_in (pos d.d_name) then DisplayEmitter.display_module_type ctx_m (match c.cl_kind with KAbstractImpl a -> TAbstractDecl a | _ -> TClassDecl c) (pos d.d_name); - TypeloadCheck.check_global_metadata ctx_m c.cl_meta (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None; + (match c.cl_kind with + | KAbstractImpl _ -> () + | _ -> TypeloadCheck.check_global_metadata ctx_m c.cl_meta (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None + ); let herits = d.d_flags in List.iter (fun (m,_,p) -> if m = Meta.Final then begin diff --git a/tests/misc/projects/Issue11545/Macro.hx b/tests/misc/projects/Issue11545/Macro.hx new file mode 100644 index 00000000000..e2ef32ec14b --- /dev/null +++ b/tests/misc/projects/Issue11545/Macro.hx @@ -0,0 +1,30 @@ +#if macro +import haxe.macro.Compiler; +import haxe.macro.Context; +import haxe.macro.Expr; + +class Macro { + public static function initMacro() { + Compiler.addGlobalMetadata("Main", "@:build(Macro.instrumentFields())", true, true, false); + } + + static function instrumentFields():Null> { + var fields:Array = Context.getBuildFields(); + for (field in fields) { + switch (field.kind) { + case FFun(f): + if (f.expr == null) { + continue; + } + switch (f.expr.expr) { + case EBlock(exprs): + exprs.unshift(macro trace($v{field.name})); + case _: + } + case _: + } + } + return fields; + } +} +#end diff --git a/tests/misc/projects/Issue11545/Main.hx b/tests/misc/projects/Issue11545/Main.hx new file mode 100644 index 00000000000..715e75f1b07 --- /dev/null +++ b/tests/misc/projects/Issue11545/Main.hx @@ -0,0 +1,12 @@ +class Main { + static function main() { + var name = new ImageName("abc"); + trace(name); + } +} + +abstract ImageName(String) { + public function new(name:String) { + this = name; + } +} diff --git a/tests/misc/projects/Issue11545/compile.hxml b/tests/misc/projects/Issue11545/compile.hxml new file mode 100644 index 00000000000..edb63433c3b --- /dev/null +++ b/tests/misc/projects/Issue11545/compile.hxml @@ -0,0 +1,2 @@ +--macro Macro.initMacro() +--run Main diff --git a/tests/misc/projects/Issue11545/compile.hxml.stdout b/tests/misc/projects/Issue11545/compile.hxml.stdout new file mode 100644 index 00000000000..91b293171ec --- /dev/null +++ b/tests/misc/projects/Issue11545/compile.hxml.stdout @@ -0,0 +1,3 @@ +Macro.hx:21: main +Macro.hx:21: _new +Main.hx:4: abc From 3f13b750ba4ce1bfd52983b3c2247d010cb1f176 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Mon, 5 Feb 2024 08:23:45 +0100 Subject: [PATCH 13/13] 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 --- src-json/meta.json | 7 ---- src/codegen/gencommon/normalize.ml | 2 +- src/context/typecore.ml | 39 ++++++++----------- src/typing/functionArguments.ml | 16 ++++---- src/typing/macroContext.ml | 28 ++++++------- src/typing/typeload.ml | 1 - src/typing/typeloadFields.ml | 19 +++++---- src/typing/typeloadFunction.ml | 3 -- src/typing/typer.ml | 26 ++++++------- src/typing/typerDisplay.ml | 1 - tests/misc/projects/Issue11538/M.hx | 3 ++ tests/misc/projects/Issue11538/Main.hx | 25 ++++++++++++ tests/misc/projects/Issue11538/compile.hxml | 2 + .../projects/Issue11538/compile.hxml.stdout | 1 + 14 files changed, 97 insertions(+), 76 deletions(-) create mode 100644 tests/misc/projects/Issue11538/M.hx create mode 100644 tests/misc/projects/Issue11538/Main.hx create mode 100644 tests/misc/projects/Issue11538/compile.hxml create mode 100644 tests/misc/projects/Issue11538/compile.hxml.stdout diff --git a/src-json/meta.json b/src-json/meta.json index 9df0fb365e6..8d5d7b9e1f6 100644 --- a/src-json/meta.json +++ b/src-json/meta.json @@ -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", diff --git a/src/codegen/gencommon/normalize.ml b/src/codegen/gencommon/normalize.ml index 2758423ef55..5072a609734 100644 --- a/src/codegen/gencommon/normalize.ml +++ b/src/codegen/gencommon/normalize.ml @@ -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 diff --git a/src/context/typecore.ml b/src/context/typecore.ml index 730c05259b8..b0db1b0ff73 100644 --- a/src/context/typecore.ml +++ b/src/context/typecore.ml @@ -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; @@ -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; @@ -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; } @@ -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 = @@ -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 @@ -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 diff --git a/src/typing/functionArguments.ml b/src/typing/functionArguments.ml index cba9c2add66..f7251a69ca3 100644 --- a/src/typing/functionArguments.ml +++ b/src/typing/functionArguments.ml @@ -4,7 +4,7 @@ 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 @@ -12,9 +12,9 @@ let type_function_arg ctx t e opt 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 = @@ -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) @@ -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 @@ -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 -> @@ -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 @@ -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 diff --git a/src/typing/macroContext.ml b/src/typing/macroContext.ml index b17f1a2b103..225c211339d 100644 --- a/src/typing/macroContext.ml +++ b/src/typing/macroContext.ml @@ -57,7 +57,7 @@ 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) @@ -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... *) 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 -> @@ -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) -> @@ -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 -> @@ -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 @@ -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; @@ -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 diff --git a/src/typing/typeload.ml b/src/typing/typeload.ml index 7bc27105321..bfba81c88ac 100644 --- a/src/typing/typeload.ml +++ b/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 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); diff --git a/src/typing/typeloadFields.ml b/src/typing/typeloadFields.ml index f49140384ff..200470095e2 100644 --- a/src/typing/typeloadFields.ml +++ b/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 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 = @@ -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); @@ -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 @@ -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 = @@ -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; @@ -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))) diff --git a/src/typing/typeloadFunction.ml b/src/typing/typeloadFunction.ml index d3dff29cd54..9e8b073b3c6 100644 --- a/src/typing/typeloadFunction.ml +++ b/src/typing/typeloadFunction.ml @@ -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 = diff --git a/src/typing/typer.ml b/src/typing/typer.ml index 57778ec4f16..25e48f28733 100644 --- a/src/typing/typer.ml +++ b/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 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 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 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 end; let v,pname = (match name with | None -> None,p | Some (v,pn) -> Some v,pn ) 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; if not inline then ctx.e.in_loop <- false; 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 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 maybe_unify_arg t1 t2 = 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); Some v ) 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 ctx.type_params <- old_tp; - ctx.e.in_loop <- old_in_loop; let tf = { - tf_args = args#for_expr; + tf_args = args#for_expr ctx; tf_type = rt; tf_expr = e; } in diff --git a/src/typing/typerDisplay.ml b/src/typing/typerDisplay.ml index 9470e8bae60..7734c359d90 100644 --- a/src/typing/typerDisplay.ml +++ b/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) | DisplayException(DisplayFields ({fkind = CRTypeHint} as r)) when (match fst e_ast with ENew _ -> true | _ -> false) -> let timer = Timer.timer ["display";"toplevel";"filter ctors"] in - ctx.pass <- PBuildClass; let l = List.filter (fun item -> let is_private_to_current_module mt = (* Remove the _Module nonsense from the package *) diff --git a/tests/misc/projects/Issue11538/M.hx b/tests/misc/projects/Issue11538/M.hx new file mode 100644 index 00000000000..e9d9ac1c27a --- /dev/null +++ b/tests/misc/projects/Issue11538/M.hx @@ -0,0 +1,3 @@ +class M { + static public var x:Float; +} diff --git a/tests/misc/projects/Issue11538/Main.hx b/tests/misc/projects/Issue11538/Main.hx new file mode 100644 index 00000000000..58d58e3cb93 --- /dev/null +++ b/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 { + 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 +} diff --git a/tests/misc/projects/Issue11538/compile.hxml b/tests/misc/projects/Issue11538/compile.hxml new file mode 100644 index 00000000000..b30a755894b --- /dev/null +++ b/tests/misc/projects/Issue11538/compile.hxml @@ -0,0 +1,2 @@ +--main Main +--interp \ No newline at end of file diff --git a/tests/misc/projects/Issue11538/compile.hxml.stdout b/tests/misc/projects/Issue11538/compile.hxml.stdout new file mode 100644 index 00000000000..b41a42411d0 --- /dev/null +++ b/tests/misc/projects/Issue11538/compile.hxml.stdout @@ -0,0 +1 @@ +Main.hx:23: Float \ No newline at end of file