|
@@ -338,6 +338,13 @@ let fast_eq_check type_param_check a b =
|
|
|
c1 == c2 && List.for_all2 type_param_check l1 l2
|
|
|
| TAbstract (a1,l1), TAbstract (a2,l2) ->
|
|
|
a1 == a2 && List.for_all2 type_param_check l1 l2
|
|
|
+ | TAnon an1,TAnon an2 ->
|
|
|
+ begin match !(an1.a_status),!(an2.a_status) with
|
|
|
+ | ClassStatics c, ClassStatics c2 -> c == c2
|
|
|
+ | EnumStatics e, EnumStatics e2 -> e == e2
|
|
|
+ | AbstractStatics a, AbstractStatics a2 -> a == a2
|
|
|
+ | _ -> false
|
|
|
+ end
|
|
|
| _ , _ ->
|
|
|
false
|
|
|
|
|
@@ -386,9 +393,6 @@ let rec shallow_eq a b =
|
|
|
loop (List.sort sort_compare fields1) (List.sort sort_compare fields2)
|
|
|
in
|
|
|
(match !(a2.a_status), !(a1.a_status) with
|
|
|
- | ClassStatics c, ClassStatics c2 -> c == c2
|
|
|
- | EnumStatics e, EnumStatics e2 -> e == e2
|
|
|
- | AbstractStatics a, AbstractStatics a2 -> a == a2
|
|
|
| Extend tl1, Extend tl2 -> fields_eq() && List.for_all2 shallow_eq tl1 tl2
|
|
|
| Closed, Closed -> fields_eq()
|
|
|
| Const, Const -> fields_eq()
|
|
@@ -565,6 +569,10 @@ let rec type_eq uctx a b =
|
|
|
| AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
|
|
|
| _ -> ()
|
|
|
);
|
|
|
+ let fields = match !(a1.a_status) with
|
|
|
+ | ClassStatics c -> c.cl_statics
|
|
|
+ | _ -> a1.a_fields
|
|
|
+ in
|
|
|
PMap.iter (fun n f1 ->
|
|
|
try
|
|
|
let f2 = PMap.find n a2.a_fields in
|
|
@@ -575,9 +583,9 @@ let rec type_eq uctx a b =
|
|
|
with
|
|
|
Not_found ->
|
|
|
error [has_no_field b n];
|
|
|
- ) a1.a_fields;
|
|
|
+ ) fields;
|
|
|
PMap.iter (fun n f2 ->
|
|
|
- if not (PMap.mem n a1.a_fields) then begin
|
|
|
+ if not (PMap.mem n fields) then begin
|
|
|
error [has_no_field a n];
|
|
|
end;
|
|
|
) a2.a_fields;
|
|
@@ -897,39 +905,58 @@ let rec unify (uctx : unification_context) a b =
|
|
|
error [cannot_unify a b]
|
|
|
|
|
|
and unify_anons uctx a b a1 a2 =
|
|
|
- (try
|
|
|
- PMap.iter (fun n f2 ->
|
|
|
+ let unify_field a1_fields f2 =
|
|
|
+ let n = f2.cf_name in
|
|
|
+ let f1 = PMap.find n a1_fields in
|
|
|
+ if not (unify_kind f1.cf_kind f2.cf_kind) then
|
|
|
+ error [invalid_kind n f1.cf_kind f2.cf_kind];
|
|
|
+ if (has_class_field_flag f2 CfPublic) && not (has_class_field_flag f1 CfPublic) then
|
|
|
+ error [invalid_visibility n];
|
|
|
try
|
|
|
- let f1 = PMap.find n a1.a_fields in
|
|
|
- if not (unify_kind f1.cf_kind f2.cf_kind) then
|
|
|
- error [invalid_kind n f1.cf_kind f2.cf_kind];
|
|
|
- if (has_class_field_flag f2 CfPublic) && not (has_class_field_flag f1 CfPublic) then error [invalid_visibility n];
|
|
|
- try
|
|
|
- let f1_type =
|
|
|
- if fast_eq f1.cf_type f2.cf_type then f1.cf_type
|
|
|
- else field_type f1
|
|
|
- in
|
|
|
- unify_with_access uctx f1 f1_type f2;
|
|
|
- (match !(a1.a_status) with
|
|
|
- | ClassStatics c when not (Meta.has Meta.MaybeUsed f1.cf_meta) -> f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta
|
|
|
- | _ -> ());
|
|
|
- with
|
|
|
- Unify_error l -> error (invalid_field n :: l)
|
|
|
- with
|
|
|
- Not_found ->
|
|
|
- match !(a1.a_status) with
|
|
|
- | Const when Meta.has Meta.Optional f2.cf_meta ->
|
|
|
- a1.a_fields <- PMap.add f2.cf_name f2 a1.a_fields
|
|
|
- | _ ->
|
|
|
- error [has_no_field a n];
|
|
|
- ) a2.a_fields;
|
|
|
- (match !(a2.a_status) with
|
|
|
- | ClassStatics c -> (match !(a1.a_status) with ClassStatics c2 when c == c2 -> () | _ -> error [])
|
|
|
- | EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
|
|
|
- | AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
|
|
|
- | Const | Extend _ | Closed -> ())
|
|
|
- with
|
|
|
- Unify_error l -> error (cannot_unify a b :: l))
|
|
|
+ let f1_type =
|
|
|
+ if fast_eq f1.cf_type f2.cf_type then f1.cf_type
|
|
|
+ else field_type f1
|
|
|
+ in
|
|
|
+ unify_with_access uctx f1 f1_type f2;
|
|
|
+ f1
|
|
|
+ with Unify_error l ->
|
|
|
+ error (invalid_field n :: l)
|
|
|
+ in
|
|
|
+ let unify_fields a1_fields f_good f_bad =
|
|
|
+ try
|
|
|
+ PMap.iter (fun _ f2 ->
|
|
|
+ try
|
|
|
+ f_good (unify_field a1_fields f2)
|
|
|
+ with Not_found ->
|
|
|
+ if not (f_bad f2) then
|
|
|
+ error [has_no_field a f2.cf_name]
|
|
|
+ ) a2.a_fields
|
|
|
+ with Unify_error l ->
|
|
|
+ error (cannot_unify a b :: l)
|
|
|
+ in
|
|
|
+ begin match !(a1.a_status),!(a2.a_status) with
|
|
|
+ | ClassStatics c1,ClassStatics c2 when c1 == c2 ->
|
|
|
+ ()
|
|
|
+ | EnumStatics en1,EnumStatics en2 when en1 == en2 ->
|
|
|
+ ()
|
|
|
+ | AbstractStatics a1,AbstractStatics a2 when a1 == a2 ->
|
|
|
+ ()
|
|
|
+ | Const,_ ->
|
|
|
+ unify_fields a1.a_fields (fun _ -> ()) (fun f2 ->
|
|
|
+ if Meta.has Meta.Optional f2.cf_meta then begin
|
|
|
+ a1.a_fields <- PMap.add f2.cf_name f2 a1.a_fields;
|
|
|
+ true
|
|
|
+ end else
|
|
|
+ false
|
|
|
+ )
|
|
|
+ | ClassStatics c1,_ ->
|
|
|
+ unify_fields c1.cl_statics (fun f1 ->
|
|
|
+ if not (Meta.has Meta.MaybeUsed f1.cf_meta) then
|
|
|
+ f1.cf_meta <- (Meta.MaybeUsed,[],f1.cf_pos) :: f1.cf_meta
|
|
|
+ ) (fun _ -> false)
|
|
|
+ | _ ->
|
|
|
+ unify_fields a1.a_fields (fun _ -> ()) (fun _ -> false)
|
|
|
+ end
|
|
|
|
|
|
and does_func_unify f =
|
|
|
try f(); true with Unify_error _ -> false
|