Skip to content

Commit 4f7da57

Browse files
committed
coerce elgible variants to float
1 parent 0743b86 commit 4f7da57

7 files changed

+49
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/variant_coercion_float.res:5:10-19
4+
5+
3 │ let x = One(true)
6+
4 │
7+
5 │ let y = (x :> float)
8+
6 │
9+
10+
Type x is not a subtype of float
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
We've found a bug for you!
3+
/.../fixtures/variant_coercion_float_as.res:5:10-19
4+
5+
3 │ let x = One
6+
4 │
7+
5 │ let y = (x :> float)
8+
6 │
9+
10+
Type x is not a subtype of float
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type x = | @as(1.1) One(bool) | @as(2.2) Two
2+
3+
let x = One(true)
4+
5+
let y = (x :> float)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type x = | @as(1.1) One | Two
2+
3+
let x = One
4+
5+
let y = (x :> float)

jscomp/ml/ctype.ml

+8
Original file line numberDiff line numberDiff line change
@@ -3967,6 +3967,14 @@ let rec subtype_rec env trace t1 t2 cstrs =
39673967
else
39683968
(trace, t1, t2, !univar_pairs)::cstrs
39693969
| _ -> (trace, t1, t2, !univar_pairs)::cstrs)
3970+
| (Tconstr(_, [], _), Tconstr(p, [], _)) when Path.same p Predef.path_float -> (* type coercion for variants represented by floats *)
3971+
(match extract_concrete_typedecl env t1 with
3972+
| (_, _, {type_kind=Type_variant (constructors)}) ->
3973+
if Variant_coercion.can_coerce_to_float constructors then
3974+
cstrs
3975+
else
3976+
(trace, t1, t2, !univar_pairs)::cstrs
3977+
| _ -> (trace, t1, t2, !univar_pairs)::cstrs)
39703978
| (Tconstr(_, [], _), Tconstr(_, [], _)) -> (* type coercion for records *)
39713979
(match extract_concrete_typedecl env t1, extract_concrete_typedecl env t2 with
39723980
| (_, _, {type_kind=Type_record (fields1, repr1)}), (_, _, {type_kind=Type_record (fields2, repr2)}) ->

jscomp/ml/variant_coercion.ml

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
type variant_representation = String | Int | Other
2+
type variant_representation = String | Int | Float | Other
33

44
let find_as_attribute_payload (attributes : Parsetree.attribute list) =
55
attributes
@@ -23,6 +23,7 @@ let constructors_representations
2323
match (c.cd_args, c.cd_attributes |> find_as_attribute_payload) with
2424
| Cstr_tuple [], (Some (Pconst_string _) | None) -> String
2525
| Cstr_tuple [], Some (Pconst_integer _) -> Int
26+
| Cstr_tuple [], Some (Pconst_float _) -> Float
2627
| _ -> Other)
2728

2829
(* TODO: Improve error messages? Say why we can't coerce. *)
@@ -32,3 +33,6 @@ let can_coerce_to_string (constructors : Types.constructor_declaration list) =
3233

3334
let can_coerce_to_int (constructors : Types.constructor_declaration list) =
3435
constructors |> constructors_representations |> List.for_all (( = ) Int)
36+
37+
let can_coerce_to_float (constructors : Types.constructor_declaration list) =
38+
constructors |> constructors_representations |> List.for_all (( = ) Float)

jscomp/test/VariantCoercion.res

+6
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ type onlyInts = | @as(1) One1 | @as(2) Two2 | @as(3) Three3
99
let i = One1
1010

1111
let d = (i :> int)
12+
13+
type onlyFloats = | @as(1.1) Onef | @as(2.2) Twof | @as(3.3) Threef
14+
15+
let i = Onef
16+
17+
let d = (i :> float)

0 commit comments

Comments
 (0)