@@ -53,8 +53,9 @@ open Btype
53
53
*)
54
54
55
55
(* *** Errors ****)
56
+ type type_pairs = (type_expr * type_expr ) list
56
57
57
- exception Unify of (type_expr * type_expr) list
58
+ exception Unify of type_pairs
58
59
59
60
exception Tags of label * label
60
61
@@ -100,11 +101,20 @@ type subtype_context =
100
101
issues : Record_coercion .record_field_subtype_violation list ;
101
102
}
102
103
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
+
103
112
exception
104
113
Subtype of
105
- (type_expr * type_expr) list
106
- * (type_expr * type_expr) list
114
+ type_pairs
115
+ * type_pairs
107
116
* subtype_context option
117
+ * subtype_type_position option
108
118
109
119
exception Cannot_expand
110
120
@@ -113,7 +123,7 @@ exception Cannot_apply
113
123
exception Recursive_abbrev
114
124
115
125
(* 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
117
127
118
128
(* *** Type level management ****)
119
129
@@ -3579,15 +3589,15 @@ let enlarge_type env ty =
3579
3589
3580
3590
let subtypes = TypePairs. create 17
3581
3591
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 ))
3584
3594
3585
3595
let extract_concrete_typedecl_opt env t =
3586
3596
match extract_concrete_typedecl env t with
3587
3597
| v -> Some v
3588
3598
| exception Not_found -> None
3589
3599
3590
- let rec subtype_rec env trace t1 t2 cstrs =
3600
+ let rec subtype_rec ? type_position env trace t1 t2 cstrs =
3591
3601
let t1 = repr t1 in
3592
3602
let t2 = repr t2 in
3593
3603
if t1 == t2 then cstrs
@@ -3598,14 +3608,16 @@ let rec subtype_rec env trace t1 t2 cstrs =
3598
3608
with Not_found -> (
3599
3609
TypePairs. add subtypes (t1, t2) () ;
3600
3610
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
3602
3613
| Tarrow (l1, t1, u1, _, _), Tarrow (l2, t2, u2, _, _)
3603
3614
when Asttypes.Noloc. same_arg_label l1 l2 ->
3604
3615
let cstrs = subtype_rec env ((t2, t1) :: trace) t2 t1 cstrs in
3605
3616
subtype_rec env ((u1, u2) :: trace) u1 u2 cstrs
3606
3617
| 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
3609
3621
| Tconstr (p1 , [] , _ ), Tconstr (p2 , [] , _ ) when Path. same p1 p2 -> cstrs
3610
3622
| Tconstr (p1, _tl1, _abbrev1), _
3611
3623
when generic_abbrev env p1 && safe_abbrev env t1 ->
@@ -3631,13 +3643,15 @@ let rec subtype_rec env trace t1 t2 cstrs =
3631
3643
newty2 t1.level (Ttuple [t1]),
3632
3644
newty2 t2.level (Ttuple [t2]),
3633
3645
! univar_pairs,
3634
- None )
3646
+ None ,
3647
+ type_position )
3635
3648
:: cstrs
3636
3649
else subtype_rec env ((t1, t2) :: trace) t1 t2 cstrs
3637
3650
else if cn then subtype_rec env ((t2, t1) :: trace) t2 t1 cstrs
3638
3651
else cstrs)
3639
3652
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)
3641
3655
| Tconstr (p1 , _ , _ ), _ when generic_private_abbrev env p1 ->
3642
3656
subtype_rec env trace (expand_abbrev_opt env t1) t2 cstrs
3643
3657
| Tconstr (p1, [] , _), Tconstr (p2, [] , _)
@@ -3664,7 +3678,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
3664
3678
! univar_pairs,
3665
3679
Some
3666
3680
(Primitive_coercion_target_variant_not_unboxed
3667
- {variant_name = p; primitive = path}) )
3681
+ {variant_name = p; primitive = path}),
3682
+ type_position )
3668
3683
:: cstrs
3669
3684
| Some (p , constructors , true ) ->
3670
3685
if
@@ -3678,11 +3693,17 @@ let rec subtype_rec env trace t1 t2 cstrs =
3678
3693
! univar_pairs,
3679
3694
Some
3680
3695
(Primitive_coercion_target_variant_no_catch_all
3681
- {variant_name = p; primitive = path}) )
3696
+ {variant_name = p; primitive = path}),
3697
+ type_position )
3682
3698
:: cstrs
3683
3699
| None ->
3684
3700
(* 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 )
3686
3707
:: cstrs)
3687
3708
| Tconstr (_, [] , _), Tconstr (path, [] , _)
3688
3709
when Variant_coercion. can_coerce_primitive path
@@ -3708,11 +3729,11 @@ let rec subtype_rec env trace t1 t2 cstrs =
3708
3729
! univar_pairs,
3709
3730
Some
3710
3731
(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 )
3713
3734
:: cstrs
3714
3735
else cstrs
3715
- | None -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
3736
+ | None -> (trace, t1, t2, ! univar_pairs, None , type_position ) :: cstrs)
3716
3737
| Tconstr (_ , [] , _ ), Tconstr (_ , [] , _ ) -> (
3717
3738
(* type coercion for variants and records *)
3718
3739
match
@@ -3722,7 +3743,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
3722
3743
(p2, _, {type_kind = Type_variant c2; type_attributes = t2attrs}) )
3723
3744
-> (
3724
3745
match
3725
- Variant_coercion. variant_configuration_can_be_coerced2 t1attrs
3746
+ Variant_coercion. variant_configuration_can_be_coerced t1attrs
3726
3747
t2attrs
3727
3748
with
3728
3749
| Error issue ->
@@ -3732,7 +3753,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
3732
3753
! univar_pairs,
3733
3754
Some
3734
3755
(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 )
3736
3758
:: cstrs
3737
3759
| Ok () ->
3738
3760
let c1_len = List. length c1 in
@@ -3760,7 +3782,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
3760
3782
issue =
3761
3783
Incompatible_constructor_count
3762
3784
{constructor_names = incompatible_constructor_names};
3763
- }) )
3785
+ }),
3786
+ type_position )
3764
3787
:: cstrs
3765
3788
else
3766
3789
let constructor_map = Hashtbl. create c1_len in
@@ -3822,7 +3845,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
3822
3845
| _ -> Some [ (* TODO(subtype-errors) *) ])
3823
3846
in
3824
3847
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)
3826
3849
| ( (p1, _, {type_kind = Type_record (fields1, repr1)}),
3827
3850
(p2, _, {type_kind = Type_record (fields2, repr2)}) ) ->
3828
3851
(* TODO(subtype-errors) Record representation *)
@@ -3850,10 +3873,24 @@ let rec subtype_rec env trace t1 t2 cstrs =
3850
3873
left_record_name = p1;
3851
3874
right_record_name = p2;
3852
3875
issues = violations;
3853
- }) )
3876
+ }),
3877
+ type_position )
3854
3878
:: 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
3857
3894
| (p1 , _ , {type_kind = tk1 } ), (p2 , _ , {type_kind = tk2 } ) ->
3858
3895
( trace,
3859
3896
t1,
@@ -3866,19 +3903,22 @@ let rec subtype_rec env trace t1 t2 cstrs =
3866
3903
right_typename = p2;
3867
3904
left_type_kind = tk1;
3868
3905
right_type_kind = tk2;
3869
- }) )
3906
+ }),
3907
+ type_position )
3870
3908
:: 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)
3872
3911
(* | (_, Tconstr(p2, _, _)) when generic_private_abbrev false env p2 ->
3873
3912
subtype_rec env trace t1 (expand_abbrev_opt env t2) cstrs *)
3874
3913
| Tobject (f1, _), Tobject (f2, _)
3875
3914
when is_Tvar (object_row f1) && is_Tvar (object_row f2) ->
3876
3915
(* Same row variable implies same object. *)
3877
- (trace, t1, t2, ! univar_pairs, None ) :: cstrs
3916
+ (trace, t1, t2, ! univar_pairs, None , type_position ) :: cstrs
3878
3917
| Tobject (f1 , _ ), Tobject (f2 , _ ) -> subtype_fields env trace f1 f2 cstrs
3879
3918
| Tvariant row1 , Tvariant row2 -> (
3880
3919
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)
3882
3922
| Tvariant {row_closed = true ; row_fields}, Tconstr (_, [] , _)
3883
3923
when extract_concrete_typedecl_opt env t2
3884
3924
|> Variant_coercion. type_is_variant -> (
@@ -3892,8 +3932,9 @@ let rec subtype_rec env trace t1 t2 cstrs =
3892
3932
~variant_constructors ~type_attributes
3893
3933
with
3894
3934
| 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)
3897
3938
| Tvariant v , _ when ! variant_is_subtype env (row_repr v) t2 -> cstrs
3898
3939
| Tpoly (u1 , [] ), Tpoly (u2 , [] ) -> subtype_rec env trace u1 u2 cstrs
3899
3940
| Tpoly (u1 , tl1 ), Tpoly (u2 , [] ) ->
@@ -3903,7 +3944,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
3903
3944
try
3904
3945
enter_poly env univar_pairs u1 tl1 u2 tl2 (fun t1 t2 ->
3905
3946
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)
3907
3949
| Tpackage (p1 , nl1 , tl1 ), Tpackage (p2 , nl2 , tl2 ) -> (
3908
3950
try
3909
3951
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 =
3914
3956
let cstrs' =
3915
3957
List. map
3916
3958
(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 ))
3918
3965
ntl2
3919
3966
in
3920
3967
if eq_package_path env p1 p2 then cstrs' @ cstrs
3921
3968
else
3922
3969
(* need to check module subtyping *)
3923
3970
let snap = Btype. snapshot () in
3924
3971
try
3925
- List. iter (fun (_ , t1 , t2 , _ , _ ) -> unify env t1 t2) cstrs';
3972
+ List. iter (fun (_ , t1 , t2 , _ , _ , _ ) -> unify env t1 t2) cstrs';
3926
3973
if ! package_subtype env p1 nl1 tl1 p2 nl2 tl2 then (
3927
3974
Btype. backtrack snap;
3928
3975
cstrs' @ cstrs)
3929
3976
else raise (Unify [] )
3930
3977
with Unify _ ->
3931
3978
Btype. backtrack snap;
3932
3979
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
3938
3989
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)
3940
3999
cstrs tl1 tl2
3941
4000
3942
- and subtype_fields env trace ty1 ty2 cstrs =
4001
+ and subtype_fields ? type_position env trace ty1 ty2 cstrs =
3943
4002
(* Assume that either rest1 or rest2 is not Tvar *)
3944
4003
let fields1, rest1 = flatten_fields ty1 in
3945
4004
let fields2, rest2 = flatten_fields ty2 in
@@ -3953,7 +4012,8 @@ and subtype_fields env trace ty1 ty2 cstrs =
3953
4012
build_fields (repr ty1).level miss1 rest1,
3954
4013
rest2,
3955
4014
! univar_pairs,
3956
- None )
4015
+ None ,
4016
+ type_position )
3957
4017
:: cstrs
3958
4018
in
3959
4019
let cstrs =
@@ -3963,7 +4023,8 @@ and subtype_fields env trace ty1 ty2 cstrs =
3963
4023
rest1,
3964
4024
build_fields (repr ty2).level miss2 (newvar () ),
3965
4025
! univar_pairs,
3966
- None )
4026
+ None ,
4027
+ type_position )
3967
4028
:: cstrs
3968
4029
in
3969
4030
List. fold_left
@@ -4020,14 +4081,15 @@ let subtype env ty1 ty2 =
4020
4081
| () ->
4021
4082
List. iter
4022
4083
(function
4023
- | trace0 , t1 , t2 , pairs , ctx -> (
4084
+ | trace0 , t1 , t2 , pairs , ctx , type_position -> (
4024
4085
try unify_pairs (ref env) t1 t2 pairs
4025
4086
with Unify trace ->
4026
4087
raise
4027
4088
(Subtype
4028
4089
( expand_trace env (List. rev trace0),
4029
4090
List. tl (List. tl trace),
4030
- ctx ))))
4091
+ ctx,
4092
+ type_position ))))
4031
4093
(List. rev cstrs)
4032
4094
4033
4095
(* ******************)
0 commit comments