Skip to content

Commit 55476b9

Browse files
committed
more hints about what types we are looking at
1 parent 83bfd76 commit 55476b9

10 files changed

+206
-97
lines changed

compiler/ml/ctype.ml

Lines changed: 107 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -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

5960
exception 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+
103112
exception
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

109119
exception Cannot_expand
110120

@@ -113,7 +123,7 @@ exception Cannot_apply
113123
exception 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

35803590
let 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

35853595
let 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
(*******************)

compiler/ml/ctype.mli

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
open Asttypes
1919
open Types
2020

21+
type type_pairs = (type_expr * type_expr) list
22+
2123
type subtype_context =
2224
| Generic of {errorCode: string}
2325
| Primitive_coercion_target_variant_not_unboxed of {
@@ -49,17 +51,26 @@ type subtype_context =
4951
issues: Record_coercion.record_field_subtype_violation list;
5052
}
5153

52-
exception Unify of (type_expr * type_expr) list
54+
type subtype_type_position =
55+
| RecordField of {
56+
field_name: string;
57+
left_record_name: Path.t;
58+
right_record_name: Path.t;
59+
}
60+
| TupleElement of {index: int}
61+
62+
exception Unify of type_pairs
5363
exception Tags of label * label
5464
exception
5565
Subtype of
56-
(type_expr * type_expr) list
57-
* (type_expr * type_expr) list
66+
type_pairs
67+
* type_pairs
5868
* subtype_context option
69+
* subtype_type_position option
5970
exception Cannot_expand
6071
exception Cannot_apply
6172
exception Recursive_abbrev
62-
exception Unification_recursive_abbrev of (type_expr * type_expr) list
73+
exception Unification_recursive_abbrev of type_pairs
6374

6475
val init_def : int -> unit
6576
(* Set the initial variable level *)

0 commit comments

Comments
 (0)