@@ -14,10 +14,25 @@ type value = {
1414
1515type type_ = { tname : string ; tdiff : (type_declaration , type_modification ) t }
1616
17- and type_modification =
18- | Record_diff of record_field list
19- | Variant_diff of constructor_ list
20- | Atomic of type_declaration atomic_modification
17+ and type_modification = {
18+ type_kind : (Types .type_decl_kind , type_kind ) maybe_changed ;
19+ type_privacy : (Asttypes .private_flag , type_privacy ) maybe_changed ;
20+ type_manifest :
21+ ( type_expr option ,
22+ (type_expr , type_expr atomic_modification ) t )
23+ maybe_changed ;
24+ }
25+
26+ and ('same, 'different) maybe_changed =
27+ | Same of 'same
28+ | Different of 'different
29+
30+ and type_privacy = Added_p | Removed_p
31+
32+ and type_kind =
33+ | Record_tk of record_field list
34+ | Variant_tk of constructor_ list
35+ | Atomic_tk of type_decl_kind atomic_modification
2136
2237and record_field = {
2338 rname : string ;
@@ -35,7 +50,7 @@ and constructor_modification =
3550 | Atomic_c of constructor_declaration atomic_modification
3651
3752and tuple_component =
38- (type_expr, (type_expr, type_expr atomic_modification) t) Either. t
53+ (type_expr, (type_expr, type_expr atomic_modification) t) maybe_changed
3954
4055type class_ = {
4156 cname : string ;
@@ -112,6 +127,10 @@ let module_type_fallback ~loc ~typing_env ~name ~reference ~current =
112127 | exception Includemod. Error _ ->
113128 Some (Module { mname = name; mdiff = Modified Unsupported })
114129
130+ let type_expr typing_env reference current =
131+ if Ctype. does_match typing_env reference current then None
132+ else Some (Modified { reference; current })
133+
115134let extract_lbls lbls =
116135 List. fold_left
117136 (fun map lbl -> String_map. add (Ident. name lbl.ld_id) lbl map)
@@ -129,54 +148,67 @@ let rec type_item ~typing_env ~name ~reference ~current =
129148 Some (Type { tname = name; tdiff = Removed reference })
130149 | None , Some (current , _ ) ->
131150 Some (Type { tname = name; tdiff = Added current })
132- | Some (reference , refId ), Some (current , curId ) -> (
133- let type_coercion1 () =
134- Includecore. type_declarations ~loc: current.type_loc typing_env
135- ~mark: false name current (Pident curId) reference
151+ | Some (reference , _ ), Some (current , _ ) ->
152+ type_decls ~typing_env ~name ~reference ~current
153+
154+ and type_decls ~typing_env ~name ~reference ~current =
155+ let type_kind =
156+ type_kind ~typing_env ~ref_type_kind: reference.type_kind
157+ ~cur_type_kind: current.type_kind
158+ in
159+ let type_privacy =
160+ type_privacy ~ref_type_privacy: reference.type_private
161+ ~cur_type_privacy: current.type_private
162+ in
163+ let type_manifest =
164+ type_manifest ~typing_env ~ref_type_manifest: reference.type_manifest
165+ ~cur_type_manifest: current.type_manifest
166+ in
167+ match { type_kind; type_privacy; type_manifest } with
168+ | { type_kind = Same _ ; type_privacy = Same _ ; type_manifest = Same _ } ->
169+ None
170+ | diff -> Some (Type { tname = name; tdiff = Modified diff })
171+
172+ and type_privacy ~ref_type_privacy ~cur_type_privacy =
173+ match (ref_type_privacy, cur_type_privacy) with
174+ | Asttypes. Public , Asttypes. Public -> Same Asttypes. Public
175+ | Asttypes. Public , Asttypes. Private -> Different Added_p
176+ | Asttypes. Private , Asttypes. Public -> Different Removed_p
177+ | Asttypes. Private , Asttypes. Private -> Same Asttypes. Private
178+
179+ and type_kind ~typing_env ~ref_type_kind ~cur_type_kind =
180+ match (ref_type_kind, cur_type_kind) with
181+ | (Type_record (ref_label_lst , _ ) as td ), Type_record (cur_label_lst , _ ) -> (
182+ let changed_lbls =
183+ modified_record_type ~typing_env ~ref_label_lst ~cur_label_lst
136184 in
137- let type_coercion2 () =
138- Includecore. type_declarations ~loc: reference.type_loc typing_env
139- ~mark: false name reference (Pident refId) current
185+ match changed_lbls with
186+ | [] -> Same td
187+ | _ -> Different (Record_tk changed_lbls))
188+ | ( (Type_variant (ref_constructor_lst, _) as td),
189+ Type_variant (cur_constructor_lst, _) ) -> (
190+ let changed_constrs =
191+ modified_variant_type ~typing_env ~ref_constructor_lst
192+ ~cur_constructor_lst
140193 in
141- match (type_coercion1 () , type_coercion2 () ) with
142- | None , None -> None
143- | _ , _ -> (
144- match (reference.type_kind, current.type_kind) with
145- | Type_record (ref_label_lst , _ ), Type_record (cur_label_lst , _ ) -> (
146- let changed_lbls =
147- modified_record_type ~typing_env ~ref_label_lst ~cur_label_lst
148- in
149- match changed_lbls with
150- | [] -> None
151- | _ ->
152- Some
153- (Type
154- {
155- tname = name;
156- tdiff = Modified (Record_diff changed_lbls);
157- }))
158- | ( Type_variant (ref_constructor_lst, _),
159- Type_variant (cur_constructor_lst, _) ) -> (
160- let changed_constrs =
161- modified_variant_type ~typing_env ~ref_constructor_lst
162- ~cur_constructor_lst
163- in
164- match changed_constrs with
165- | [] -> None
166- | _ ->
167- Some
168- (Type
169- {
170- tname = name;
171- tdiff = Modified (Variant_diff changed_constrs);
172- }))
173- | _ ->
174- Some
175- (Type
176- {
177- tname = name;
178- tdiff = Modified (Atomic { reference; current });
179- })))
194+ match changed_constrs with
195+ | [] -> Same td
196+ | _ -> Different (Variant_tk changed_constrs))
197+ | (Type_abstract _ as td ), Type_abstract _ -> Same td
198+ | (Type_open as td ), Type_open -> Same td
199+ | ref_type_kind , cur_type_kind ->
200+ Different
201+ (Atomic_tk { reference = ref_type_kind; current = cur_type_kind })
202+
203+ and type_manifest ~typing_env ~ref_type_manifest ~cur_type_manifest =
204+ match (ref_type_manifest, cur_type_manifest) with
205+ | None , None -> Same None
206+ | Some t1 , None -> Different (Removed t1)
207+ | None , Some t2 -> Different (Added t2)
208+ | Some t1 , Some t2 -> (
209+ match type_expr typing_env t1 t2 with
210+ | None -> Same (Some t1)
211+ | Some diff -> Different diff)
180212
181213and modified_variant_type ~typing_env ~ref_constructor_lst ~cur_constructor_lst
182214 =
@@ -186,8 +218,7 @@ and modified_variant_type ~typing_env ~ref_constructor_lst ~cur_constructor_lst
186218 let tuple_diff = modified_tuple_type ~typing_env type_lst1 type_lst2 in
187219 if
188220 List. for_all
189- (fun t ->
190- match t with Either. Left _ -> true | Either. Right _ -> false )
221+ (fun t -> match t with Same _ -> true | Different _ -> false )
191222 tuple_diff
192223 then None
193224 else Some { csname = name; csdiff = Modified (Tuple_c tuple_diff) }
@@ -219,8 +250,8 @@ and modified_variant_type ~typing_env ~ref_constructor_lst ~cur_constructor_lst
219250 in
220251 modified_cstrs
221252
222- and diff_list (diff_one : 'a option -> 'a option -> ('a, 'diff) Either.t )
223- (ref : 'a list ) (curr : 'a list ) : ('a, 'diff) Either.t list =
253+ and diff_list (diff_one : 'a option -> 'a option -> ('a, 'diff) maybe_changed )
254+ (ref : 'a list ) (curr : 'a list ) : ('a, 'diff) maybe_changed list =
224255 match (ref , curr) with
225256 | [] , [] -> []
226257 | h1 :: t1 , [] -> diff_one (Some h1) None :: diff_list diff_one t1 []
@@ -234,11 +265,12 @@ and modified_tuple_type ~typing_env (ref_tuple : type_expr list)
234265 (fun t1 t2 ->
235266 match (t1, t2) with
236267 | None , None -> assert false
237- | Some t1 , None -> Either. right (Removed t1)
238- | None , Some t2 -> Either. right (Added t2)
239- | Some t1 , Some t2 ->
240- if Ctype. does_match typing_env t1 t2 then Either. left t1
241- else Either. right (Modified { reference = t1; current = t2 }))
268+ | Some t1 , None -> Different (Removed t1)
269+ | None , Some t2 -> Different (Added t2)
270+ | Some t1 , Some t2 -> (
271+ match type_expr typing_env t1 t2 with
272+ | None -> Same t1
273+ | Some diff -> Different diff))
242274 ref_tuple cur_tuple
243275
244276and modified_record_type ~typing_env ~(ref_label_lst : label_declaration list )
@@ -252,14 +284,15 @@ and modified_record_type ~typing_env ~(ref_label_lst : label_declaration list)
252284 | None , None -> None
253285 | Some ref , None -> Some { rname = name; rdiff = Removed ref }
254286 | None , Some cur -> Some { rname = name; rdiff = Added cur }
255- | Some ref , Some cur ->
256- if Ctype. does_match typing_env ref .ld_type cur.ld_type then None
257- else
258- Some
259- {
260- rname = name;
261- rdiff = Modified { reference = ref ; current = cur };
262- })
287+ | Some ref , Some cur -> (
288+ match type_expr typing_env ref .ld_type cur.ld_type with
289+ | None -> None
290+ | Some _ ->
291+ Some
292+ {
293+ rname = name;
294+ rdiff = Modified { reference = ref ; current = cur };
295+ }))
263296 ref_lbls curr_lbls
264297 |> String_map. bindings |> List. map snd
265298 in
0 commit comments