@@ -3979,16 +3979,23 @@ let rec subtype_rec env trace t1 t2 cstrs =
3979
3979
Hashtbl. add constructor_map (Ident. name c.cd_id) c);
3980
3980
if c1 |> List. for_all (fun (c : Types.constructor_declaration ) ->
3981
3981
match (c, Hashtbl. find_opt constructor_map (Ident. name c.cd_id)) with
3982
- | ( {Types. cd_args = Cstr_record _fields1},
3983
- Some {Types. cd_args = Cstr_record _fields2} ) ->
3984
- (* TODO: Reuse logic from record coercion *)
3985
- false
3982
+ | ( {Types. cd_args = Cstr_record fields1; cd_attributes= c1_attributes},
3983
+ Some {Types. cd_args = Cstr_record fields2; cd_attributes= c2_attributes} ) ->
3984
+ if Variant_coercion. variant_representation_matches c1_attributes c2_attributes then
3985
+ let violation, tl1, tl2 = Record_coercion. check_record_fields fields1 fields2 in
3986
+ if violation then false
3987
+ else
3988
+ begin try
3989
+ let lst = subtype_list env trace tl1 tl2 cstrs in
3990
+ List. length lst = List. length cstrs
3991
+ with | _ -> false end
3992
+ else false
3986
3993
| ( {Types. cd_args = Cstr_tuple tl1; cd_attributes= c1_attributes},
3987
3994
Some {Types. cd_args = Cstr_tuple tl2; cd_attributes= c2_attributes} ) ->
3988
3995
if Variant_coercion. variant_representation_matches c1_attributes c2_attributes then
3989
3996
begin try
3990
- let lst = subtype_list env trace tl1 tl2 cstrs in
3991
- List. length lst = List. length cstrs
3997
+ let lst = subtype_list env trace tl1 tl2 cstrs in
3998
+ List. length lst = List. length cstrs
3992
3999
with | _ -> false end
3993
4000
else false
3994
4001
| _ -> false )
@@ -4003,30 +4010,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
4003
4010
| Record_extension , Record_extension -> true
4004
4011
| _ -> false in
4005
4012
if same_repr then
4006
- let field_is_optional id repr = match repr with
4007
- | Record_optional_labels lbls -> List. mem (Ident. name id) lbls
4008
- | _ -> false in
4009
- let violation = ref false in
4010
- let label_decl_sub (acc1 , acc2 ) ld2 =
4011
- match Ext_list. find_first fields1 (fun ld1 -> ld1.ld_id.name = ld2.ld_id.name) with
4012
- | Some ld1 ->
4013
- if field_is_optional ld1.ld_id repr1 <> (field_is_optional ld2.ld_id repr2) then
4014
- (* optional field can't be modified *)
4015
- violation := true ;
4016
- let get_as (({txt} , payload ) : Parsetree. attribute ) =
4017
- if txt = " as" then Ast_payload. is_single_string payload
4018
- else None in
4019
- let get_as_name ld = match Ext_list. filter_map ld.ld_attributes get_as with
4020
- | [] -> ld.ld_id.name
4021
- | (s ,_ )::_ -> s in
4022
- if get_as_name ld1 <> get_as_name ld2 then violation := true ;
4023
- ld1.ld_type :: acc1, ld2.ld_type :: acc2
4024
- | None ->
4025
- (* field must be present *)
4026
- violation := true ;
4027
- (acc1, acc2) in
4028
- let tl1, tl2 = List. fold_left label_decl_sub ([] , [] ) fields2 in
4029
- if ! violation
4013
+ let violation, tl1, tl2 = Record_coercion. check_record_fields ~repr1 ~repr2 fields1 fields2 in
4014
+ if violation
4030
4015
then (trace, t1, t2, ! univar_pairs)::cstrs
4031
4016
else
4032
4017
subtype_list env trace tl1 tl2 cstrs
0 commit comments