Skip to content

Commit

Permalink
Add support for typer coercion for invariant type arguments such as a…
Browse files Browse the repository at this point in the history
…rray 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.
  • Loading branch information
cristianoc authored Dec 11, 2023
1 parent adb55d0 commit 35e8c71
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
10 changes: 8 additions & 2 deletions jscomp/ml/ctype.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3939,8 +3939,14 @@ let rec subtype_rec env trace t1 t2 cstrs =
let (co, cn) = Variance.get_upper v in
if co then
if cn then
(trace, newty2 t1.level (Ttuple[t1]),
newty2 t2.level (Ttuple[t2]), !univar_pairs) :: cstrs
(* Invariant type argument: check both ways *)
if
subtype_rec env ((t1, t2)::trace) t1 t2 [] = [] &&
subtype_rec env ((t2, t1)::trace) t2 t1 [] = [] then
cstrs
else
(trace, newty2 t1.level (Ttuple[t1]),
newty2 t2.level (Ttuple[t2]), !univar_pairs) :: cstrs
else subtype_rec env ((t1, t2)::trace) t1 t2 cstrs
else
if cn then subtype_rec env ((t2, t1)::trace) t2 t1 cstrs
Expand Down
5 changes: 5 additions & 0 deletions jscomp/test/Coercion.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions jscomp/test/Coercion.res
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
let x = 1

let xx = (x :> float)

type r1 = {x:int}
type r2 = {x:int}

type t1 = array<r1>
type t2 = array<r2>

let foo = (x: t1) => { x :> t2 }

0 comments on commit 35e8c71

Please sign in to comment.