@@ -53,8 +53,9 @@ open Btype
5353*)
5454
5555(* *** Errors ****)
56+ type type_pairs = (type_expr * type_expr ) list
5657
57- exception Unify of (type_expr * type_expr) list
58+ exception Unify of type_pairs
5859
5960exception Tags of label * label
6061
@@ -100,11 +101,20 @@ type subtype_context =
100101 issues : Record_coercion .record_field_subtype_violation list ;
101102 }
102103
104+ type subtype_type_position =
105+ | RecordField of {
106+ field_name : string ;
107+ left_record_name : Path .t ;
108+ right_record_name : Path .t ;
109+ }
110+ | TupleElement of {index : int }
111+
103112exception
104113 Subtype of
105- (type_expr * type_expr) list
106- * (type_expr * type_expr) list
114+ type_pairs
115+ * type_pairs
107116 * subtype_context option
117+ * subtype_type_position option
108118
109119exception Cannot_expand
110120
@@ -113,7 +123,7 @@ exception Cannot_apply
113123exception Recursive_abbrev
114124
115125(* GADT: recursive abbrevs can appear as a result of local constraints *)
116- exception Unification_recursive_abbrev of (type_expr * type_expr) list
126+ exception Unification_recursive_abbrev of type_pairs
117127
118128(* *** Type level management ****)
119129
@@ -3579,15 +3589,15 @@ let enlarge_type env ty =
35793589
35803590let subtypes = TypePairs. create 17
35813591
3582- let subtype_error ?ctx env trace =
3583- raise (Subtype (expand_trace env (List. rev trace), [] , ctx))
3592+ let subtype_error ?type_position ? ctx env trace =
3593+ raise (Subtype (expand_trace env (List. rev trace), [] , ctx, type_position ))
35843594
35853595let extract_concrete_typedecl_opt env t =
35863596 match extract_concrete_typedecl env t with
35873597 | v -> Some v
35883598 | exception Not_found -> None
35893599
3590- let rec subtype_rec env trace t1 t2 cstrs =
3600+ let rec subtype_rec ? type_position env trace t1 t2 cstrs =
35913601 let t1 = repr t1 in
35923602 let t2 = repr t2 in
35933603 if t1 == t2 then cstrs
@@ -3598,14 +3608,16 @@ let rec subtype_rec env trace t1 t2 cstrs =
35983608 with Not_found -> (
35993609 TypePairs. add subtypes (t1, t2) () ;
36003610 match (t1.desc, t2.desc) with
3601- | Tvar _ , _ | _ , Tvar _ -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs
3611+ | Tvar _ , _ | _ , Tvar _ ->
3612+ (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs
36023613 | Tarrow (l1, t1, u1, _, _), Tarrow (l2, t2, u2, _, _)
36033614 when Asttypes.Noloc. same_arg_label l1 l2 ->
36043615 let cstrs = subtype_rec env ((t2, t1) :: trace) t2 t1 cstrs in
36053616 subtype_rec env ((u1, u2) :: trace) u1 u2 cstrs
36063617 | Ttuple tl1 , Ttuple tl2 ->
3607- (* TODO(subtype-errors) Tuple as context *)
3608- subtype_list env trace tl1 tl2 cstrs
3618+ subtype_list
3619+ ~make_type_position: (fun i -> Some (TupleElement {index = i}))
3620+ env trace tl1 tl2 cstrs
36093621 | Tconstr (p1 , [] , _ ), Tconstr (p2 , [] , _ ) when Path. same p1 p2 -> cstrs
36103622 | Tconstr (p1, _tl1, _abbrev1), _
36113623 when generic_abbrev env p1 && safe_abbrev env t1 ->
@@ -3631,13 +3643,15 @@ let rec subtype_rec env trace t1 t2 cstrs =
36313643 newty2 t1.level (Ttuple [t1]),
36323644 newty2 t2.level (Ttuple [t2]),
36333645 ! univar_pairs,
3634- None )
3646+ None ,
3647+ type_position )
36353648 :: cstrs
36363649 else subtype_rec env ((t1, t2) :: trace) t1 t2 cstrs
36373650 else if cn then subtype_rec env ((t2, t1) :: trace) t2 t1 cstrs
36383651 else cstrs)
36393652 cstrs decl.type_variance (List. combine tl1 tl2)
3640- with Not_found -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3653+ with Not_found ->
3654+ (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs)
36413655 | Tconstr (p1 , _ , _ ), _ when generic_private_abbrev env p1 ->
36423656 subtype_rec env trace (expand_abbrev_opt env t1) t2 cstrs
36433657 | Tconstr (p1, [] , _), Tconstr (p2, [] , _)
@@ -3664,7 +3678,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
36643678 ! univar_pairs,
36653679 Some
36663680 (Primitive_coercion_target_variant_not_unboxed
3667- {variant_name = p; primitive = path}) )
3681+ {variant_name = p; primitive = path}),
3682+ type_position )
36683683 :: cstrs
36693684 | Some (p , constructors , true ) ->
36703685 if
@@ -3678,11 +3693,17 @@ let rec subtype_rec env trace t1 t2 cstrs =
36783693 ! univar_pairs,
36793694 Some
36803695 (Primitive_coercion_target_variant_no_catch_all
3681- {variant_name = p; primitive = path}) )
3696+ {variant_name = p; primitive = path}),
3697+ type_position )
36823698 :: cstrs
36833699 | None ->
36843700 (* Unclear when this case actually happens. *)
3685- (trace, t1, t2, ! univar_pairs, Some (Generic {errorCode = " VCPMMVD" }))
3701+ ( trace,
3702+ t1,
3703+ t2,
3704+ ! univar_pairs,
3705+ Some (Generic {errorCode = " VCPMMVD" }),
3706+ type_position )
36863707 :: cstrs)
36873708 | Tconstr (_, [] , _), Tconstr (path, [] , _)
36883709 when Variant_coercion. can_coerce_primitive path
@@ -3708,11 +3729,11 @@ let rec subtype_rec env trace t1 t2 cstrs =
37083729 ! univar_pairs,
37093730 Some
37103731 (Variant_constructor_runtime_representation_mismatch
3711- {issues = runtime_representation_issues; variant_name = p})
3712- )
3732+ {issues = runtime_representation_issues; variant_name = p}),
3733+ type_position )
37133734 :: cstrs
37143735 else cstrs
3715- | None -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3736+ | None -> (trace, t1, t2, ! univar_pairs, None , type_position ) :: cstrs)
37163737 | Tconstr (_ , [] , _ ), Tconstr (_ , [] , _ ) -> (
37173738 (* type coercion for variants and records *)
37183739 match
@@ -3722,7 +3743,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
37223743 (p2, _, {type_kind = Type_variant c2; type_attributes = t2attrs}) )
37233744 -> (
37243745 match
3725- Variant_coercion. variant_configuration_can_be_coerced2 t1attrs
3746+ Variant_coercion. variant_configuration_can_be_coerced t1attrs
37263747 t2attrs
37273748 with
37283749 | Error issue ->
@@ -3732,7 +3753,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
37323753 ! univar_pairs,
37333754 Some
37343755 (Variant_configurations_mismatch
3735- {left_variant_name = p1; right_variant_name = p2; issue}) )
3756+ {left_variant_name = p1; right_variant_name = p2; issue}),
3757+ type_position )
37363758 :: cstrs
37373759 | Ok () ->
37383760 let c1_len = List. length c1 in
@@ -3760,7 +3782,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
37603782 issue =
37613783 Incompatible_constructor_count
37623784 {constructor_names = incompatible_constructor_names};
3763- }) )
3785+ }),
3786+ type_position )
37643787 :: cstrs
37653788 else
37663789 let constructor_map = Hashtbl. create c1_len in
@@ -3822,7 +3845,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
38223845 | _ -> Some [ (* TODO(subtype-errors) *) ])
38233846 in
38243847 if field_subtype_violations = [] then cstrs
3825- else (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3848+ else (trace, t1, t2, ! univar_pairs, None , type_position ) :: cstrs)
38263849 | ( (p1, _, {type_kind = Type_record (fields1, repr1)}),
38273850 (p2, _, {type_kind = Type_record (fields2, repr2)}) ) ->
38283851 (* TODO(subtype-errors) Record representation *)
@@ -3850,10 +3873,24 @@ let rec subtype_rec env trace t1 t2 cstrs =
38503873 left_record_name = p1;
38513874 right_record_name = p2;
38523875 issues = violations;
3853- }) )
3876+ }),
3877+ type_position )
38543878 :: cstrs
3855- else subtype_list env trace tl1 tl2 cstrs
3856- else (trace, t1, t2, ! univar_pairs, None ) :: cstrs
3879+ else
3880+ subtype_list
3881+ ~make_type_position: (fun i ->
3882+ match List. nth_opt fields1 i with
3883+ | None -> None
3884+ | Some field ->
3885+ Some
3886+ (RecordField
3887+ {
3888+ field_name = field.ld_id.name;
3889+ left_record_name = p1;
3890+ right_record_name = p2;
3891+ }))
3892+ env trace tl1 tl2 cstrs
3893+ else (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs
38573894 | (p1 , _ , {type_kind = tk1 } ), (p2 , _ , {type_kind = tk2 } ) ->
38583895 ( trace,
38593896 t1,
@@ -3866,19 +3903,22 @@ let rec subtype_rec env trace t1 t2 cstrs =
38663903 right_typename = p2;
38673904 left_type_kind = tk1;
38683905 right_type_kind = tk2;
3869- }) )
3906+ }),
3907+ type_position )
38703908 :: cstrs
3871- | exception Not_found -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3909+ | exception Not_found ->
3910+ (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs)
38723911 (* | (_, Tconstr(p2, _, _)) when generic_private_abbrev false env p2 ->
38733912 subtype_rec env trace t1 (expand_abbrev_opt env t2) cstrs *)
38743913 | Tobject (f1, _), Tobject (f2, _)
38753914 when is_Tvar (object_row f1) && is_Tvar (object_row f2) ->
38763915 (* Same row variable implies same object. *)
3877- (trace, t1, t2, ! univar_pairs, None ) :: cstrs
3916+ (trace, t1, t2, ! univar_pairs, None , type_position ) :: cstrs
38783917 | Tobject (f1 , _ ), Tobject (f2 , _ ) -> subtype_fields env trace f1 f2 cstrs
38793918 | Tvariant row1 , Tvariant row2 -> (
38803919 try subtype_row env trace row1 row2 cstrs
3881- with Exit -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3920+ with Exit ->
3921+ (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs)
38823922 | Tvariant {row_closed = true ; row_fields}, Tconstr (_, [] , _)
38833923 when extract_concrete_typedecl_opt env t2
38843924 |> Variant_coercion. type_is_variant -> (
@@ -3892,8 +3932,9 @@ let rec subtype_rec env trace t1 t2 cstrs =
38923932 ~variant_constructors ~type_attributes
38933933 with
38943934 | Ok _ -> cstrs
3895- | Error _ -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3896- | _ -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3935+ | Error _ ->
3936+ (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs)
3937+ | _ -> (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs)
38973938 | Tvariant v , _ when ! variant_is_subtype env (row_repr v) t2 -> cstrs
38983939 | Tpoly (u1 , [] ), Tpoly (u2 , [] ) -> subtype_rec env trace u1 u2 cstrs
38993940 | Tpoly (u1 , tl1 ), Tpoly (u2 , [] ) ->
@@ -3903,7 +3944,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
39033944 try
39043945 enter_poly env univar_pairs u1 tl1 u2 tl2 (fun t1 t2 ->
39053946 subtype_rec env trace t1 t2 cstrs)
3906- with Unify _ -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3947+ with Unify _ ->
3948+ (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs)
39073949 | Tpackage (p1 , nl1 , tl1 ), Tpackage (p2 , nl2 , tl2 ) -> (
39083950 try
39093951 let ntl1 = complete_type_list env nl2 t1.level (Mty_ident p1) nl1 tl1
@@ -3914,32 +3956,49 @@ let rec subtype_rec env trace t1 t2 cstrs =
39143956 let cstrs' =
39153957 List. map
39163958 (fun (n2 , t2 ) ->
3917- (trace, List. assoc n2 ntl1, t2, ! univar_pairs, None ))
3959+ ( trace,
3960+ List. assoc n2 ntl1,
3961+ t2,
3962+ ! univar_pairs,
3963+ None ,
3964+ type_position ))
39183965 ntl2
39193966 in
39203967 if eq_package_path env p1 p2 then cstrs' @ cstrs
39213968 else
39223969 (* need to check module subtyping *)
39233970 let snap = Btype. snapshot () in
39243971 try
3925- List. iter (fun (_ , t1 , t2 , _ , _ ) -> unify env t1 t2) cstrs';
3972+ List. iter (fun (_ , t1 , t2 , _ , _ , _ ) -> unify env t1 t2) cstrs';
39263973 if ! package_subtype env p1 nl1 tl1 p2 nl2 tl2 then (
39273974 Btype. backtrack snap;
39283975 cstrs' @ cstrs)
39293976 else raise (Unify [] )
39303977 with Unify _ ->
39313978 Btype. backtrack snap;
39323979 raise Not_found
3933- with Not_found -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3934- | _ , _ -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3935-
3936- and subtype_list env trace tl1 tl2 cstrs =
3937- if List. length tl1 <> List. length tl2 then subtype_error env trace;
3980+ with Not_found ->
3981+ (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs)
3982+ | _ , _ -> (trace, t1, t2, ! univar_pairs, None , type_position) :: cstrs)
3983+
3984+ and subtype_list ?make_type_position env trace tl1 tl2 cstrs =
3985+ if List. length tl1 <> List. length tl2 then
3986+ (* TODO(subtype-errors): Not the same length error *)
3987+ subtype_error env trace;
3988+ let idx = ref 0 in
39383989 List. fold_left2
3939- (fun cstrs t1 t2 -> subtype_rec env ((t1, t2) :: trace) t1 t2 cstrs)
3990+ (fun cstrs t1 t2 ->
3991+ let index = ! idx in
3992+ incr idx;
3993+ let type_position =
3994+ match make_type_position with
3995+ | Some f -> f index
3996+ | None -> None
3997+ in
3998+ subtype_rec ?type_position env ((t1, t2) :: trace) t1 t2 cstrs)
39403999 cstrs tl1 tl2
39414000
3942- and subtype_fields env trace ty1 ty2 cstrs =
4001+ and subtype_fields ? type_position env trace ty1 ty2 cstrs =
39434002 (* Assume that either rest1 or rest2 is not Tvar *)
39444003 let fields1, rest1 = flatten_fields ty1 in
39454004 let fields2, rest2 = flatten_fields ty2 in
@@ -3953,7 +4012,8 @@ and subtype_fields env trace ty1 ty2 cstrs =
39534012 build_fields (repr ty1).level miss1 rest1,
39544013 rest2,
39554014 ! univar_pairs,
3956- None )
4015+ None ,
4016+ type_position )
39574017 :: cstrs
39584018 in
39594019 let cstrs =
@@ -3963,7 +4023,8 @@ and subtype_fields env trace ty1 ty2 cstrs =
39634023 rest1,
39644024 build_fields (repr ty2).level miss2 (newvar () ),
39654025 ! univar_pairs,
3966- None )
4026+ None ,
4027+ type_position )
39674028 :: cstrs
39684029 in
39694030 List. fold_left
@@ -4020,14 +4081,15 @@ let subtype env ty1 ty2 =
40204081 | () ->
40214082 List. iter
40224083 (function
4023- | trace0 , t1 , t2 , pairs , ctx -> (
4084+ | trace0 , t1 , t2 , pairs , ctx , type_position -> (
40244085 try unify_pairs (ref env) t1 t2 pairs
40254086 with Unify trace ->
40264087 raise
40274088 (Subtype
40284089 ( expand_trace env (List. rev trace0),
40294090 List. tl (List. tl trace),
4030- ctx ))))
4091+ ctx,
4092+ type_position ))))
40314093 (List. rev cstrs)
40324094
40334095(* ******************)
0 commit comments