@@ -3951,7 +3951,33 @@ let rec subtype_rec env trace t1 t2 cstrs =
39513951 end
39523952 | (Tconstr(p1 , _ , _ ), _ ) when generic_private_abbrev env p1 ->
39533953 subtype_rec env trace (expand_abbrev_opt env t1) t2 cstrs
3954- (* | (_, Tconstr(p2, _, _)) when generic_private_abbrev false env p2 ->
3954+ | (Tconstr(_ , [] , _ ), Tconstr(_ , [] , _ )) -> (* type coercion for records *)
3955+ (match extract_concrete_typedecl env t1, extract_concrete_typedecl env t2 with
3956+ | (_ , _ , {type_kind =Type_record (fields1 , repr1 )} ), (_ , _ , {type_kind =Type_record (fields2 , repr2 )} ) ->
3957+ let field_is_optional id repr = match repr with
3958+ | Record_optional_labels lbls -> List. mem (Ident. name id) lbls
3959+ | _ -> false in
3960+ let violation = ref false in
3961+ let label_decl_sub (acc1 , acc2 ) ld2 =
3962+ match fields1 |> List. find_opt (fun ld1 -> Ident. name ld1.ld_id = Ident. name ld2.ld_id) with
3963+ | Some ld1 ->
3964+ if field_is_optional ld1.ld_id repr1 && not (field_is_optional ld2.ld_id repr2) then
3965+ (* optional field can't be cast to non-optional one *)
3966+ violation := true ;
3967+ ld1.ld_type :: acc1, ld2.ld_type :: acc2
3968+ | None ->
3969+ (* field must be present *)
3970+ violation := true ;
3971+ (acc1, acc2) in
3972+ let tl1, tl2 = List. fold_left label_decl_sub ([] , [] ) fields2 in
3973+ if ! violation
3974+ then (trace, t1, t2, ! univar_pairs)::cstrs
3975+ else
3976+ subtype_list env trace tl1 tl2 cstrs
3977+ | _ -> (trace, t1, t2, ! univar_pairs)::cstrs
3978+ | exception Not_found -> (trace, t1, t2, ! univar_pairs)::cstrs
3979+ )
3980+ (* | (_, Tconstr(p2, _, _)) when generic_private_abbrev false env p2 ->
39553981 subtype_rec env trace t1 (expand_abbrev_opt env t2) cstrs *)
39563982 | (Tobject (f1, _), Tobject (f2, _))
39573983 when is_Tvar (object_row f1) && is_Tvar (object_row f2) ->
0 commit comments