|
@@ -29,7 +29,7 @@ type eq_kind =
|
|
|
| EqRightDynamic
|
|
|
| EqBothDynamic
|
|
|
| EqDoNotFollowNull (* like EqStrict, but does not follow Null<T> *)
|
|
|
- | EqStrictStrict (* TODO *)
|
|
|
+ | EqStricter
|
|
|
|
|
|
type unification_context = {
|
|
|
allow_transitive_cast : bool;
|
|
@@ -432,7 +432,7 @@ let direct_access = function
|
|
|
| AccNo | AccNever | AccNormal | AccInline | AccRequire _ | AccCtor -> true
|
|
|
| AccCall -> false
|
|
|
|
|
|
-let unify_kind ?(strict:bool = false) k1 k2 =
|
|
|
+let unify_kind ~(strict:bool) k1 k2 =
|
|
|
k1 = k2 || match k1, k2 with
|
|
|
| Var v1, Var v2 -> unify_access v1.v_read v2.v_read && unify_access v1.v_write v2.v_write
|
|
|
| Method m1, Method m2 ->
|
|
@@ -495,8 +495,12 @@ let rec_stack_default stack value fcheck frun def =
|
|
|
|
|
|
let rec type_eq uctx a b =
|
|
|
let param = uctx.equality_kind in
|
|
|
+ let can_follow_null = match param with
|
|
|
+ | EqStricter | EqDoNotFollowNull -> false
|
|
|
+ | _ -> true
|
|
|
+ in
|
|
|
let can_follow t = match param with
|
|
|
- | EqStrictStrict -> false
|
|
|
+ | EqStricter -> false
|
|
|
| EqCoreType -> false
|
|
|
| EqDoNotFollowNull -> not (is_explicit_null t)
|
|
|
| _ -> true
|
|
@@ -528,9 +532,9 @@ let rec type_eq uctx a b =
|
|
|
()
|
|
|
| TAbstract ({a_path=[],"Null"},[t1]),TAbstract ({a_path=[],"Null"},[t2]) ->
|
|
|
type_eq uctx t1 t2
|
|
|
- | TAbstract ({a_path=[],"Null"},[t]),_ when param <> EqDoNotFollowNull && param <> EqStrictStrict ->
|
|
|
+ | TAbstract ({a_path=[],"Null"},[t]),_ when can_follow_null ->
|
|
|
type_eq uctx t b
|
|
|
- | _,TAbstract ({a_path=[],"Null"},[t]) when param <> EqDoNotFollowNull && param <> EqStrictStrict ->
|
|
|
+ | _,TAbstract ({a_path=[],"Null"},[t]) when can_follow_null ->
|
|
|
type_eq uctx 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 ->
|
|
|
type_eq_params uctx a b tl1 tl2
|
|
@@ -584,7 +588,11 @@ let rec type_eq uctx a b =
|
|
|
PMap.iter (fun n f1 ->
|
|
|
try
|
|
|
let f2 = PMap.find n a2.a_fields in
|
|
|
- if f1.cf_kind <> f2.cf_kind && (param = EqStrict || param = EqCoreType || param = EqDoNotFollowNull || param = EqStrictStrict || not (unify_kind ~strict:uctx.strict_field_kind f1.cf_kind f2.cf_kind)) then error [invalid_kind n f1.cf_kind f2.cf_kind];
|
|
|
+ let kind_should_match = match param with
|
|
|
+ | EqStrict | EqCoreType | EqDoNotFollowNull | EqStricter -> true
|
|
|
+ | _ -> false
|
|
|
+ in
|
|
|
+ if f1.cf_kind <> f2.cf_kind && (kind_should_match || not (unify_kind ~strict:uctx.strict_field_kind f1.cf_kind f2.cf_kind)) then error [invalid_kind n f1.cf_kind f2.cf_kind];
|
|
|
let a = f1.cf_type and b = f2.cf_type in
|
|
|
(try type_eq uctx a b with Unify_error l -> error (invalid_field n :: l));
|
|
|
if (has_class_field_flag f1 CfPublic) != (has_class_field_flag f2 CfPublic) then error [invalid_visibility n];
|