Skip to content

Commit 9ef31a8

Browse files
committed
different type kinds
1 parent 002fbe1 commit 9ef31a8

File tree

5 files changed

+69
-5
lines changed

5 files changed

+69
-5
lines changed

compiler/ml/ctype.ml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ type subtype_context =
8888
right_variant_name: Path.t;
8989
issue: Variant_coercion.variant_configuration_issue;
9090
}
91+
| Different_type_kinds of {
92+
left_typename: Path.t;
93+
right_typename: Path.t;
94+
left_type_kind: type_kind;
95+
right_type_kind: type_kind;
96+
}
9197

9298
exception
9399
Subtype of
@@ -3777,6 +3783,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
37773783
Variant_coercion.variant_representation_matches
37783784
c1_attributes c2_attributes
37793785
then
3786+
(* TODO(subtype-errors) Inline record coercion check, piggy back on record coercion check *)
37803787
let violation, tl1, tl2 =
37813788
Record_coercion.check_record_fields fields1 fields2
37823789
in
@@ -3810,6 +3817,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
38103817
else (trace, t1, t2, !univar_pairs, None) :: cstrs)
38113818
| ( (_, _, {type_kind = Type_record (fields1, repr1)}),
38123819
(_, _, {type_kind = Type_record (fields2, repr2)}) ) ->
3820+
(* TODO(subtype-errors) Record representation *)
38133821
let same_repr =
38143822
match (repr1, repr2) with
38153823
| Record_regular, Record_regular ->
@@ -3826,7 +3834,20 @@ let rec subtype_rec env trace t1 t2 cstrs =
38263834
if violation then (trace, t1, t2, !univar_pairs, None) :: cstrs
38273835
else subtype_list env trace tl1 tl2 cstrs
38283836
else (trace, t1, t2, !univar_pairs, None) :: cstrs
3829-
| _ -> (trace, t1, t2, !univar_pairs, None) :: cstrs
3837+
| (p1, _, {type_kind = tk1}), (p2, _, {type_kind = tk2}) ->
3838+
( trace,
3839+
t1,
3840+
t2,
3841+
!univar_pairs,
3842+
Some
3843+
(Different_type_kinds
3844+
{
3845+
left_typename = p1;
3846+
right_typename = p2;
3847+
left_type_kind = tk1;
3848+
right_type_kind = tk2;
3849+
}) )
3850+
:: cstrs
38303851
| exception Not_found -> (trace, t1, t2, !univar_pairs, None) :: cstrs)
38313852
(* | (_, Tconstr(p2, _, _)) when generic_private_abbrev false env p2 ->
38323853
subtype_rec env trace t1 (expand_abbrev_opt env t2) cstrs *)

compiler/ml/ctype.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ type subtype_context =
3737
right_variant_name: Path.t;
3838
issue: Variant_coercion.variant_configuration_issue;
3939
}
40+
| Different_type_kinds of {
41+
left_typename: Path.t;
42+
right_typename: Path.t;
43+
left_type_kind: type_kind;
44+
right_type_kind: type_kind;
45+
}
4046

4147
exception Unify of (type_expr * type_expr) list
4248
exception Tags of label * label

compiler/ml/printtyp.ml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1651,9 +1651,9 @@ let report_subtyping_error ppf env tr1 txt1 tr2 ctx =
16511651
(trace false (mis = None) "is not compatible with type")
16521652
tr2 (explanation true mis));
16531653
match ctx with
1654-
| Some ctx ->
1654+
| Some ctx -> (
16551655
fprintf ppf "@,@,@[<v 2>";
1656-
(match ctx with
1656+
match ctx with
16571657
| Generic {errorCode} -> fprintf ppf "Error: %s" errorCode
16581658
| Primitive_coercion_target_variant_not_unboxed
16591659
{variant_name; primitive} ->
@@ -1684,8 +1684,22 @@ let report_subtyping_error ppf env tr1 txt1 tr2 ctx =
16841684
| Variant_configurations_mismatch
16851685
{left_variant_name; right_variant_name; issue} ->
16861686
print_variant_configuration_issue ppf issue ~left_variant_name
1687-
~right_variant_name);
1688-
fprintf ppf "@]"
1687+
~right_variant_name
1688+
| Different_type_kinds
1689+
{left_typename; right_typename; left_type_kind; right_type_kind} ->
1690+
let type_kind_to_string = function
1691+
| Type_abstract -> "an abstract type"
1692+
| Type_record _ -> "a record"
1693+
| Type_variant _ -> "a variant"
1694+
| Type_open -> "an open type"
1695+
in
1696+
fprintf ppf
1697+
"@ The types of @{<info>%s@} and @{<info>%s@} are different:"
1698+
(Path.name left_typename) (Path.name right_typename);
1699+
fprintf ppf "@ - @{<info>%s@} is %s" (Path.name left_typename)
1700+
(type_kind_to_string left_type_kind);
1701+
fprintf ppf "@ - @{<info>%s@} is %s" (Path.name right_typename)
1702+
(type_kind_to_string right_type_kind))
16891703
| None -> ())
16901704

16911705
let report_ambiguous_type_error ppf env (tp0, tp0') tpl txt1 txt2 txt3 =
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/variant_coercion_mismatching_types.res:9:10-15
4+
5+
7 │ let x: x = One(true)
6+
8 │
7+
9 │ let y = (x :> y)
8+
10 │
9+
10+
Type x is not a subtype of y
11+
12+
The types of x and y are different:
13+
- x is a variant
14+
- y is a record
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
type x = One(bool) | Two | Three | Four | Five
2+
type y = {
3+
x: x,
4+
y: int,
5+
}
6+
7+
let x: x = One(true)
8+
9+
let y = (x :> y)

0 commit comments

Comments
 (0)