Skip to content

Commit e8bdc6a

Browse files
OctachronArmael
authored andcommitted
unification trace: properly track universal variable renaming (#2135)
* unification trace: track univar renaming This PR fixes an inconsistency introduced by #2047 : when an universal type variable was renamed in Printtyp, the explanation part of the error message kept the original name leading to potentially confusing error messages. This PR fixes this inconsistency by keeping the whole type expression in the explanation part of the unification message instead of just its original name (and add a test for this behavior).
1 parent d85e98a commit e8bdc6a

File tree

4 files changed

+27
-11
lines changed

4 files changed

+27
-11
lines changed

testsuite/tests/typing-poly/error_messages.ml

+14
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,17 @@ Line 1, characters 21-33:
2626
Error: The universal type variable 'a cannot be generalized:
2727
it escapes its scope.
2828
|}]
29+
30+
31+
(** Check that renaming universal type variable is properly tracked
32+
in printtyp *)
33+
34+
let f (x:<a:'a; b:'a. 'a>) (y:<a:'a;b:'a>) = x = y
35+
[%%expect {|
36+
Line 4, characters 49-50:
37+
4 | let f (x:<a:'a; b:'a. 'a>) (y:<a:'a;b:'a>) = x = y
38+
^
39+
Error: This expression has type < a : 'a; b : 'a >
40+
but an expression was expected of type < a : 'a; b : 'a0. 'a0 >
41+
The universal variable 'a0 would escape its scope
42+
|}]

typing/ctype.ml

+7-5
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ module Unification_trace = struct
6666

6767
type 'a escape =
6868
| Constructor of Path.t
69-
| Univ of string option
69+
| Univ of type_expr
70+
(* The type_expr argument of [Univ] is always a [Tunivar _],
71+
we keep a [type_expr] to track renaming in {!Printtyp} *)
7072
| Self
7173
| Module_type of Path.t
7274
| Equation of 'a
@@ -1826,9 +1828,9 @@ let occur_univar env ty =
18261828
true
18271829
then
18281830
match ty.desc with
1829-
Tunivar u ->
1831+
Tunivar _ ->
18301832
if not (TypeSet.mem ty bound) then
1831-
raise Trace.(Unify [escape (Univ u)])
1833+
raise Trace.(Unify [escape (Univ ty)])
18321834
| Tpoly (ty, tyl) ->
18331835
let bound = List.fold_right TypeSet.add (List.map repr tyl) bound in
18341836
occur_rec bound ty
@@ -1879,8 +1881,8 @@ let univars_escape env univar_pairs vl ty =
18791881
Tpoly (t, tl) ->
18801882
if List.exists (fun t -> TypeSet.mem (repr t) family) tl then ()
18811883
else occur t
1882-
| Tunivar u ->
1883-
if TypeSet.mem t family then raise Trace.(Unify [escape(Univ u)])
1884+
| Tunivar _ ->
1885+
if TypeSet.mem t family then raise Trace.(Unify [escape(Univ t)])
18841886
| Tconstr (_, [], _) -> ()
18851887
| Tconstr (p, tl, _) ->
18861888
begin try

typing/ctype.mli

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ module Unification_trace: sig
2929
(** Scope escape related errors *)
3030
type 'a escape =
3131
| Constructor of Path.t
32-
| Univ of string option
32+
| Univ of type_expr
33+
(** The type_expr argument of [Univ] is always a [Tunivar _],
34+
we keep a [type_expr] to track renaming in {!Printtyp} *)
3335
| Self
3436
| Module_type of Path.t
3537
| Equation of 'a

typing/printtyp.ml

+3-5
Original file line numberDiff line numberDiff line change
@@ -1814,11 +1814,9 @@ let explain_escape intro ctx e =
18141814
| None -> ignore
18151815
| Some ctx -> dprintf "@[%t@;<1 2>%a@]" intro type_expr ctx in
18161816
match e with
1817-
| Trace.Univ Some u -> Some(
1818-
dprintf "%t@,The universal variable '%s would escape its scope"
1819-
pre u)
1820-
| Trace.Univ None ->
1821-
Some(dprintf "%t@,An universal variable would escape its scope" pre)
1817+
| Trace.Univ u -> Some(
1818+
dprintf "%t@,The universal variable %a would escape its scope"
1819+
pre type_expr u)
18221820
| Trace.Constructor p -> Some(
18231821
dprintf
18241822
"%t@,@[The type constructor@;<1 2>%a@ would escape its scope@]"

0 commit comments

Comments
 (0)