Kaynağa Gözat

Bring back forced inline (#11217)

* Alternative fix for 11005

* [tests] add test for 11102

* Move needs_inline / is_forced_inline

* Small optim
Rudy Ges 2 yıl önce
ebeveyn
işleme
6c18eb8799

+ 10 - 0
src/context/typecore.ml

@@ -455,6 +455,16 @@ let is_removable_field com f =
 			| _ -> false)
 	)
 
+let is_forced_inline c cf =
+	match c with
+	| Some { cl_kind = KAbstractImpl _ } -> true
+	| Some c when has_class_flag c CExtern -> true
+	| _ when has_class_field_flag cf CfExtern -> true
+	| _ -> false
+
+let needs_inline ctx c cf =
+	cf.cf_kind = Method MethInline && ctx.allow_inline && (ctx.g.doinline || is_forced_inline c cf)
+
 (** checks if we can access to a given class field using current context *)
 let rec can_access ctx c cf stat =
 	if (has_class_field_flag cf CfPublic) then

+ 0 - 4
src/optimization/inline.ml

@@ -6,10 +6,6 @@ open Common
 open Typecore
 open Error
 
-let needs_inline ctx is_extern_class cf =
-	cf.cf_kind = Method MethInline && ctx.allow_inline
-	&& (ctx.g.doinline || is_extern_class || has_class_field_flag cf CfExtern)
-
 let mk_untyped_call name p params =
 	{
 		eexpr = TCall({ eexpr = TIdent name; etype = t_dynamic; epos = p }, params);

+ 3 - 3
src/optimization/inlineConstructors.ml

@@ -212,7 +212,7 @@ let inline_constructors ctx original_e =
 			| TNew _, true ->
 				true, false
 			| TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})} as cf)} as c,_,_), _ ->
-				Inline.needs_inline ctx (has_class_flag c CExtern) cf, false
+				needs_inline ctx (Some c) cf, false
 			| _ -> false, false
 		in
 		is_ctor || Type.check_expr (check_for_ctors ~force_inline:is_meta_inline) e
@@ -237,7 +237,7 @@ let inline_constructors ctx original_e =
 			| TNew _, true ->
 				mark()
 			| TNew({ cl_constructor = Some ({cf_kind = Method MethInline; cf_expr = Some ({eexpr = TFunction _})} as cf)} as c,_,_), _ ->
-				if Inline.needs_inline ctx (has_class_flag c CExtern) cf then mark()
+				if needs_inline ctx (Some c) cf then mark()
 				else e
 			| _ -> e
 	in
@@ -285,7 +285,7 @@ let inline_constructors ctx original_e =
 					let f = PMap.find fname ctor.ioc_class.cl_fields in
 					begin match f.cf_params, f.cf_kind, f.cf_expr with
 					| [], Method MethInline, Some({eexpr = TFunction tf}) ->
-						if Inline.needs_inline ctx (has_class_flag ctor.ioc_class CExtern) f then
+						if needs_inline ctx (Some ctor.ioc_class) f then
 							Some (ctor.ioc_class, ctor.ioc_tparams, f, tf)
 						else
 							None

+ 1 - 1
src/optimization/optimizer.ml

@@ -349,7 +349,7 @@ let rec reduce_loop ctx e =
 				(match inl with
 				| None -> reduce_expr ctx e
 				| Some e -> reduce_loop ctx e)
-			| {eexpr = TField(ef,(FStatic(cl,cf) | FInstance(cl,_,cf)))} when needs_inline ctx (has_class_flag cl CExtern) cf && not (rec_stack_memq cf inline_stack) ->
+			| {eexpr = TField(ef,(FStatic(cl,cf) | FInstance(cl,_,cf)))} when needs_inline ctx (Some cl) cf && not (rec_stack_memq cf inline_stack) ->
 				begin match cf.cf_expr with
 				| Some {eexpr = TFunction tf} ->
 					let config = inline_config (Some cl) cf el e.etype in

+ 0 - 7
src/typing/callUnification.ml

@@ -6,13 +6,6 @@ open Typecore
 open Error
 open FieldAccess
 
-let is_forced_inline c cf =
-	match c with
-	| Some { cl_kind = KAbstractImpl _ } -> true
-	| Some c when has_class_flag c CExtern -> true
-	| _ when has_class_field_flag cf CfExtern -> true
-	| _ -> false
-
 let rec unify_call_args ctx el args r callp inline force_inline in_overload =
 	let call_error err p =
 		raise (Error (Call_error err,p,0))

+ 1 - 2
src/typing/calls.ml

@@ -34,8 +34,7 @@ let make_call ctx e params t ?(force_inline=false) p =
 				raise Exit
 		in
 		if not force_inline then begin
-			let is_extern_class = match cl with Some c -> (has_class_flag c CExtern) | _ -> false in
-			if not (Inline.needs_inline ctx is_extern_class f) then raise Exit;
+			if not (needs_inline ctx cl f) then raise Exit;
 		end else begin
 			match cl with
 			| None ->

+ 1 - 1
src/typing/typeloadFields.ml

@@ -917,7 +917,7 @@ module TypeBinding = struct
 						e
 					end in
 					e
-				| Var v when v.v_read = AccInline && ctx.g.doinline ->
+				| Var v when v.v_read = AccInline && (ctx.g.doinline || is_forced_inline (Some c) cf) ->
 					let e = require_constant_expression e "Inline variable initialization must be a constant value" in
 					begin match c.cl_kind with
 						| KAbstractImpl a when has_class_field_flag cf CfEnum && a.a_enum ->

+ 12 - 0
tests/misc/projects/Issue11102/Main.hx

@@ -0,0 +1,12 @@
+function main() {
+	var foo:Foo = 42;
+
+	switch (foo) {
+		case LCTRL:
+		case _:
+	}
+}
+
+enum abstract Foo(Int) from Int to Int {
+	var LCTRL:Foo = 224 | (1<<30);
+}

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

@@ -0,0 +1,2 @@
+-main Main
+-D no-inline