|
@@ -1697,11 +1697,11 @@ type unify_error =
|
|
| Invalid_visibility of string
|
|
| Invalid_visibility of string
|
|
| Not_matching_optional of string
|
|
| Not_matching_optional of string
|
|
| Cant_force_optional
|
|
| Cant_force_optional
|
|
- | Invariant_parameter of t * t
|
|
|
|
|
|
+ | Invariant_parameter of int
|
|
| Constraint_failure of string
|
|
| Constraint_failure of string
|
|
| Missing_overload of tclass_field * t
|
|
| Missing_overload of tclass_field * t
|
|
| FinalInvariance (* nice band name *)
|
|
| FinalInvariance (* nice band name *)
|
|
- | Invalid_function_argument of int
|
|
|
|
|
|
+ | Invalid_function_argument of int (* index *) * int (* total *)
|
|
| Invalid_return_type
|
|
| Invalid_return_type
|
|
| Unify_custom of string
|
|
| Unify_custom of string
|
|
|
|
|
|
@@ -1827,7 +1827,7 @@ let rec type_eq param a b =
|
|
| None -> if param = EqCoreType || not (link t b a) then error [cannot_unify a b]
|
|
| None -> if param = EqCoreType || not (link t b a) then error [cannot_unify a b]
|
|
| Some t -> type_eq param a t)
|
|
| Some t -> type_eq param a t)
|
|
| TType (t1,tl1), TType (t2,tl2) when (t1 == t2 || (param = EqCoreType && t1.t_path = t2.t_path)) && List.length tl1 = List.length tl2 ->
|
|
| TType (t1,tl1), TType (t2,tl2) when (t1 == t2 || (param = EqCoreType && t1.t_path = t2.t_path)) && List.length tl1 = List.length tl2 ->
|
|
- List.iter2 (type_eq param) tl1 tl2
|
|
|
|
|
|
+ type_eq_params param a b tl1 tl2
|
|
| TType (t,tl) , _ when can_follow a ->
|
|
| TType (t,tl) , _ when can_follow a ->
|
|
type_eq param (apply_params t.t_params tl t.t_type) b
|
|
type_eq param (apply_params t.t_params tl t.t_type) b
|
|
| _ , TType (t,tl) when can_follow b ->
|
|
| _ , TType (t,tl) when can_follow b ->
|
|
@@ -1837,19 +1837,24 @@ let rec type_eq param a b =
|
|
(fun l -> error (cannot_unify a b :: l))
|
|
(fun l -> error (cannot_unify a b :: l))
|
|
| TEnum (e1,tl1) , TEnum (e2,tl2) ->
|
|
| TEnum (e1,tl1) , TEnum (e2,tl2) ->
|
|
if e1 != e2 && not (param = EqCoreType && e1.e_path = e2.e_path) then error [cannot_unify a b];
|
|
if e1 != e2 && not (param = EqCoreType && e1.e_path = e2.e_path) then error [cannot_unify a b];
|
|
- List.iter2 (type_eq param) tl1 tl2
|
|
|
|
|
|
+ type_eq_params param a b tl1 tl2
|
|
| TInst (c1,tl1) , TInst (c2,tl2) ->
|
|
| TInst (c1,tl1) , TInst (c2,tl2) ->
|
|
if c1 != c2 && not (param = EqCoreType && c1.cl_path = c2.cl_path) && (match c1.cl_kind, c2.cl_kind with KExpr _, KExpr _ -> false | _ -> true) then error [cannot_unify a b];
|
|
if c1 != c2 && not (param = EqCoreType && c1.cl_path = c2.cl_path) && (match c1.cl_kind, c2.cl_kind with KExpr _, KExpr _ -> false | _ -> true) then error [cannot_unify a b];
|
|
- List.iter2 (type_eq param) tl1 tl2
|
|
|
|
|
|
+ type_eq_params param a b tl1 tl2
|
|
| TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
|
|
| TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
|
|
|
|
+ let i = ref 0 in
|
|
(try
|
|
(try
|
|
type_eq param r1 r2;
|
|
type_eq param r1 r2;
|
|
List.iter2 (fun (n,o1,t1) (_,o2,t2) ->
|
|
List.iter2 (fun (n,o1,t1) (_,o2,t2) ->
|
|
|
|
+ incr i;
|
|
if o1 <> o2 then error [Not_matching_optional n];
|
|
if o1 <> o2 then error [Not_matching_optional n];
|
|
type_eq param t1 t2
|
|
type_eq param t1 t2
|
|
) l1 l2
|
|
) l1 l2
|
|
with
|
|
with
|
|
- Unify_error l -> error (cannot_unify a b :: l))
|
|
|
|
|
|
+ Unify_error l ->
|
|
|
|
+ let msg = if !i = 0 then Invalid_return_type else Invalid_function_argument(!i,List.length l1) in
|
|
|
|
+ error (cannot_unify a b :: msg :: l)
|
|
|
|
+ )
|
|
| TDynamic a , TDynamic b ->
|
|
| TDynamic a , TDynamic b ->
|
|
type_eq param a b
|
|
type_eq param a b
|
|
| TAbstract ({a_path=[],"Null"},[t1]),TAbstract ({a_path=[],"Null"},[t2]) ->
|
|
| TAbstract ({a_path=[],"Null"},[t1]),TAbstract ({a_path=[],"Null"},[t2]) ->
|
|
@@ -1860,7 +1865,7 @@ let rec type_eq param a b =
|
|
type_eq param a t
|
|
type_eq param a t
|
|
| TAbstract (a1,tl1) , TAbstract (a2,tl2) ->
|
|
| TAbstract (a1,tl1) , TAbstract (a2,tl2) ->
|
|
if a1 != a2 && not (param = EqCoreType && a1.a_path = a2.a_path) then error [cannot_unify a b];
|
|
if a1 != a2 && not (param = EqCoreType && a1.a_path = a2.a_path) then error [cannot_unify a b];
|
|
- List.iter2 (type_eq param) tl1 tl2
|
|
|
|
|
|
+ type_eq_params param a b tl1 tl2
|
|
| TAnon a1, TAnon a2 ->
|
|
| TAnon a1, TAnon a2 ->
|
|
(try
|
|
(try
|
|
(match !(a2.a_status) with
|
|
(match !(a2.a_status) with
|
|
@@ -1899,6 +1904,17 @@ let rec type_eq param a b =
|
|
else
|
|
else
|
|
error [cannot_unify a b]
|
|
error [cannot_unify a b]
|
|
|
|
|
|
|
|
+and type_eq_params param a b tl1 tl2 =
|
|
|
|
+ let i = ref 0 in
|
|
|
|
+ List.iter2 (fun t1 t2 ->
|
|
|
|
+ incr i;
|
|
|
|
+ try
|
|
|
|
+ type_eq param t1 t2
|
|
|
|
+ with Unify_error l ->
|
|
|
|
+ let err = cannot_unify a b in
|
|
|
|
+ error (err :: (Invariant_parameter !i) :: l)
|
|
|
|
+ ) tl1 tl2
|
|
|
|
+
|
|
let type_iseq a b =
|
|
let type_iseq a b =
|
|
try
|
|
try
|
|
type_eq EqStrict a b;
|
|
type_eq EqStrict a b;
|
|
@@ -2011,7 +2027,7 @@ let rec unify a b =
|
|
) l2 l1 (* contravariance *)
|
|
) l2 l1 (* contravariance *)
|
|
with
|
|
with
|
|
Unify_error l ->
|
|
Unify_error l ->
|
|
- let msg = if !i = 0 then Invalid_return_type else Invalid_function_argument !i in
|
|
|
|
|
|
+ let msg = if !i = 0 then Invalid_return_type else Invalid_function_argument(!i,List.length l1) in
|
|
error (cannot_unify a b :: msg :: l))
|
|
error (cannot_unify a b :: msg :: l))
|
|
| TInst (c,tl) , TAnon an ->
|
|
| TInst (c,tl) , TAnon an ->
|
|
if PMap.is_empty an.a_fields then (match c.cl_kind with
|
|
if PMap.is_empty an.a_fields then (match c.cl_kind with
|
|
@@ -2330,12 +2346,14 @@ and unify_with_variance f t1 t2 =
|
|
error [cannot_unify t1 t2]
|
|
error [cannot_unify t1 t2]
|
|
|
|
|
|
and unify_type_params a b tl1 tl2 =
|
|
and unify_type_params a b tl1 tl2 =
|
|
|
|
+ let i = ref 0 in
|
|
List.iter2 (fun t1 t2 ->
|
|
List.iter2 (fun t1 t2 ->
|
|
|
|
+ incr i;
|
|
try
|
|
try
|
|
with_variance (type_eq EqRightDynamic) t1 t2
|
|
with_variance (type_eq EqRightDynamic) t1 t2
|
|
with Unify_error l ->
|
|
with Unify_error l ->
|
|
let err = cannot_unify a b in
|
|
let err = cannot_unify a b in
|
|
- error (err :: (Invariant_parameter (t1,t2)) :: l)
|
|
|
|
|
|
+ error (err :: (Invariant_parameter !i) :: l)
|
|
) tl1 tl2
|
|
) tl1 tl2
|
|
|
|
|
|
and with_variance f t1 t2 =
|
|
and with_variance f t1 t2 =
|