Skip to content

Commit 35e8c71

Browse files
authored
Add support for typer coercion for invariant type arguments such as array payloads. (#6518)
If type `t<'a>` is invariant in `'a` allow type coercion from `t<t1> ` to `t<t2>` if both `t1` can be coerced to `t2` and `t2` can be coerced to `t1`, which must imply that the runtime representations are the same.
1 parent adb55d0 commit 35e8c71

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

jscomp/ml/ctype.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3939,8 +3939,14 @@ let rec subtype_rec env trace t1 t2 cstrs =
39393939
let (co, cn) = Variance.get_upper v in
39403940
if co then
39413941
if cn then
3942-
(trace, newty2 t1.level (Ttuple[t1]),
3943-
newty2 t2.level (Ttuple[t2]), !univar_pairs) :: cstrs
3942+
(* Invariant type argument: check both ways *)
3943+
if
3944+
subtype_rec env ((t1, t2)::trace) t1 t2 [] = [] &&
3945+
subtype_rec env ((t2, t1)::trace) t2 t1 [] = [] then
3946+
cstrs
3947+
else
3948+
(trace, newty2 t1.level (Ttuple[t1]),
3949+
newty2 t2.level (Ttuple[t2]), !univar_pairs) :: cstrs
39443950
else subtype_rec env ((t1, t2)::trace) t1 t2 cstrs
39453951
else
39463952
if cn then subtype_rec env ((t2, t1)::trace) t2 t1 cstrs

jscomp/test/Coercion.js

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/test/Coercion.res

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
let x = 1
22

33
let xx = (x :> float)
4+
5+
type r1 = {x:int}
6+
type r2 = {x:int}
7+
8+
type t1 = array<r1>
9+
type t2 = array<r2>
10+
11+
let foo = (x: t1) => { x :> t2 }

0 commit comments

Comments
 (0)