Explorar o código

[cs] Only use __hx_cast when the types fail to unify (and are not Dynamic). Old behaviour can still have a fallback with -D cs_safe_casts. Fixed last failing test. Closes #2066

Cauê Waneck %!s(int64=11) %!d(string=hai) anos
pai
achega
7d5d185c7a
Modificáronse 2 ficheiros con 28 adicións e 8 borrados
  1. 19 4
      gencommon.ml
  2. 9 4
      gencs.ml

+ 19 - 4
gencommon.ml

@@ -4526,9 +4526,20 @@ struct
         match e.eexpr with
             | TCast(cast_expr, _) ->
               (* see if casting to a native generic class *)
-              let t = follow (gen.greal_type e.etype) in
-              (match t with
-                | TInst(cl, p1 :: pl) when is_hxgeneric (TClassDecl cl) ->
+              let t = gen.greal_type e.etype in
+              let unifies =
+                let ctype = gen.greal_type cast_expr.etype in
+                match follow ctype with
+                | TInst(cl,_) -> (try
+                  unify ctype t;
+                  true
+                with | Unify_error el ->
+                  false)
+                | _ -> false
+              in
+              let unifies = unifies && not (PMap.mem "cs_safe_casts" gen.gcon.defines) in
+              (match follow t with
+                | TInst(cl, p1 :: pl) when is_hxgeneric (TClassDecl cl) && not unifies ->
                   let iface = Hashtbl.find ifaces cl.cl_path in
                   mk_cast e.etype (change_expr (Type.map_expr run cast_expr) cl iface (p1 :: pl))
                 | _ -> Type.map_expr run e
@@ -6237,7 +6248,11 @@ struct
             | _ -> None
           in
           (match get_null expr with
-          | Some enull -> { enull with etype = e.etype }
+          | Some enull ->
+              if gen.gcon.platform = Cs then
+                { enull with etype = gen.greal_type e.etype }
+              else
+                mk_cast (gen.greal_type e.etype) enull
           | _ ->
             let last_unsafe = gen.gon_unsafe_cast in
             gen.gon_unsafe_cast <- (fun t t2 pos -> ());

+ 9 - 4
gencs.ml

@@ -30,7 +30,7 @@ open Printf
 open Option
 open ExtString
 
-let is_cs_basic_type t =
+let rec is_cs_basic_type t =
   match follow t with
     | TInst( { cl_path = (["haxe"], "Int32") }, [] )
     | TInst( { cl_path = (["haxe"], "Int64") }, [] )
@@ -43,6 +43,8 @@ let is_cs_basic_type t =
       true
     | TAbstract _ when like_float t ->
       true
+    | TAbstract({ a_impl = Some _ } as a,pl) ->
+      is_cs_basic_type (Codegen.Abstract.get_underlying_type a pl)
     | TEnum(e, _) when not (Meta.has Meta.Class e.e_meta) -> true
     | TInst(cl, _) when Meta.has Meta.Struct cl.cl_meta -> true
     | _ -> false
@@ -787,7 +789,9 @@ let configure gen =
   *)
   change_param_type md tl =
     let is_hxgeneric = (TypeParams.RealTypeParams.is_hxgeneric md) in
-    let ret t = match is_hxgeneric, real_type t with
+    let ret t =
+      let t_changed = real_type t in
+      match is_hxgeneric, t_changed with
       | false, _ -> t
       (*
         Because Null<> types need a special compiler treatment for many operations (e.g. boxing/unboxing),
@@ -797,9 +801,10 @@ let configure gen =
       | true, TInst ( { cl_kind = KTypeParameter _ }, _ ) -> t
       | true, TInst _
       | true, TEnum _
-      | true, TAbstract _ when is_cs_basic_type t -> t
+      | true, TAbstract _ when is_cs_basic_type t_changed -> t
       | true, TDynamic _ -> t
-      | true, _ -> dynamic_anon
+      | true, x ->
+        dynamic_anon
     in
     if is_hxgeneric && List.exists (fun t -> match follow t with | TDynamic _ -> true | _ -> false) tl then
       List.map (fun _ -> t_dynamic) tl