diff --git a/src/context/typecore.ml b/src/context/typecore.ml index 9b9ac8fe6c4..3536f4f3374 100644 --- a/src/context/typecore.ml +++ b/src/context/typecore.ml @@ -254,7 +254,10 @@ module TyperManager = struct } let clone_for_module ctx m = - create ctx m ctx.c ctx.f ctx.e PBuildModule [] + let ctx = create ctx m ctx.c ctx.f ctx.e PBuildModule [] in + ctx.allow_transform <- true; + ctx.allow_inline <- true; + ctx let clone_for_class ctx c = let c = create_ctx_c c in 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/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/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 diff --git a/src/typing/typeloadModule.ml b/src/typing/typeloadModule.ml index 6059f7d3c19..906492bcfa7 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; @@ -383,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 @@ -574,6 +571,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 = diff --git a/src/typing/typer.ml b/src/typing/typer.ml index 904a22be727..9f74c11e891 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 @@ -1303,14 +1304,14 @@ and type_local_function ctx_from 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/std/haxe/macro/Compiler.hx b/std/haxe/macro/Compiler.hx index 1ba1ed88e6f..854082e4e31 100644 --- a/std/haxe/macro/Compiler.hx +++ b/std/haxe/macro/Compiler.hx @@ -377,9 +377,10 @@ 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, true, field == null, field != null); + addGlobalMetadata(pathFilter, meta, false, field == null, field != null); } /** 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 - 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 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"); } diff --git a/tests/misc/src/Main.hx b/tests/misc/src/Main.hx index 4f387cc95d1..7e05e1da364 100644 --- a/tests/misc/src/Main.hx +++ b/tests/misc/src/Main.hx @@ -157,6 +157,9 @@ class Main { // Reorder fields from expected too expected = haxe.Json.stringify(haxe.Json.parse(expected)); } catch (_) {} + } else { + content = hideStdPositions(content); + expected = hideStdPositions(expected); } if (content != expected) { @@ -178,6 +181,14 @@ class Main { return true; } + static function hideStdPositions(content:String):String { + 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:???:")) + .join("\n"); + } + static macro function getStd() { var std = Compiler.getConfiguration().stdPath; return macro $v{std.shift()}; 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); + } +}