Browse Source

use actual class type for constructor inlining, because the type of a variable can be abstract (closes #3586)

Dan Korostelev 10 years ago
parent
commit
02205ede69
2 changed files with 23 additions and 7 deletions
  1. 7 7
      optimizer.ml
  2. 16 0
      tests/unit/src/unit/issues/Issue3586.hx

+ 7 - 7
optimizer.ml

@@ -1142,7 +1142,7 @@ let rec make_constant_expression ctx ?(concat_strings=false) e =
 *)
 
 type inline_kind =
-	| IKCtor of tfunc * tclass_field * tclass * texpr list * texpr list
+	| IKCtor of tfunc * tclass_field * tclass * texpr list * texpr list * t
 	| IKArray of texpr list * t
 	| IKStructure of (string * texpr) list
 	| IKNone
@@ -1167,8 +1167,8 @@ let inline_constructors ctx e =
 			false
 	in
 	let rec get_inline_ctor_info e = match e.eexpr with
-		| TNew ({ cl_constructor = Some ({ cf_kind = Method MethInline; cf_expr = Some { eexpr = TFunction f } } as cst) } as c,_,pl) ->
-			IKCtor (f,cst,c,pl,[])
+		| TNew ({ cl_constructor = Some ({ cf_kind = Method MethInline; cf_expr = Some { eexpr = TFunction f } } as cst) } as c,tl,pl) ->
+			IKCtor (f,cst,c,pl,[],TInst(c,tl))
 		| TObjectDecl [] | TArrayDecl [] ->
 			IKNone
 		| TArrayDecl el ->
@@ -1189,8 +1189,8 @@ let inline_constructors ctx e =
 			begin match List.rev el with
 				| e :: el ->
 					begin match get_inline_ctor_info e with
-						| IKCtor(f,cst,c,pl,e_init) ->
-							IKCtor(f,cst,c,pl,(List.rev el) @ e_init)
+						| IKCtor(f,cst,c,pl,e_init,t) ->
+							IKCtor(f,cst,c,pl,(List.rev el) @ e_init,t)
 						| _ ->
 							IKNone
 					end
@@ -1222,9 +1222,9 @@ let inline_constructors ctx e =
 			begin match eo with
 				| Some n ->
 					begin match get_inline_ctor_info n with
-					| IKCtor (f,cst,c,pl,el_init) ->
+					| IKCtor (f,cst,c,pl,el_init,t) ->
 						(* inline the constructor *)
-						(match (try type_inline ctx cst f (mk (TLocal v) v.v_type n.epos) pl ctx.t.tvoid None n.epos true with Error (Custom _,_) -> None) with
+						(match (try type_inline ctx cst f (mk (TLocal v) t n.epos) pl ctx.t.tvoid None n.epos true with Error (Custom _,_) -> None) with
 						| None -> ()
 						| Some ecst ->
 							let assigns = ref [] in

+ 16 - 0
tests/unit/src/unit/issues/Issue3586.hx

@@ -0,0 +1,16 @@
+package unit.issues;
+
+private class C<T> {
+    public var f:Array<T>;
+    public inline function new(v) f = [v];
+}
+
+@:forward(f)
+private abstract A(C<Int>) from C<Int> {}
+
+class Issue3586 extends unit.Test {
+    function test() {
+        var a:A = new C(15);
+        eq(a.f[0], 15);
+    }
+}