Skip to content
Browse files

[cs] Only use __hx_cast when the types fail to unify (and are not Dyn…

…amic). Old behaviour can still have a fallback with -D cs_safe_casts. Fixed last failing test. Closes #2066
  • Loading branch information...
1 parent b5bbcc4 commit 7d5d185c7aa7b84e95c5bbf956247da4a32acf22 @waneck waneck committed Mar 3, 2014
Showing with 28 additions and 8 deletions.
  1. +19 −4 gencommon.ml
  2. +9 −4 gencs.ml
View
23 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 -> ());
View
13 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

0 comments on commit 7d5d185

Please sign in to comment.
Something went wrong with that request. Please try again.