Skip to content

Uncurried types: distinguish 0 args, and 1 arg of type unit. #5821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ subset of the arguments, and return a curried type with the remaining ones https
- Curried after uncurried is not fused anymore: `(. x) => y => 3` is not equivalent to `(. x, y) => 3` anymore. It's instead equivalent to `(. x) => { y => 3 }`.
Also, `(. int) => string => bool` is not equivalen to `(. int, string) => bool` anymore.
These are only breaking changes for unformatted code.
- Distinguish between uncurried type `(. ()) => int`, whch takes 0 arguments, and `(. unit) => int` which takes 1 argument of type `unit` https://github.com/rescript-lang/rescript-compiler/pull/5821

#### :bug: Bug Fix

Expand Down
2 changes: 1 addition & 1 deletion jscomp/test/poly_variant_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ external on: (
@string
[
| #line((. string) => unit)
| #close((. unit) => unit)
| #close((. ()) => unit)
],
) => unit = "on"

Expand Down
4 changes: 2 additions & 2 deletions jscomp/test/reactTestUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ type undefined = Js.undefined<unit>
let undefined: undefined = Js.Undefined.empty

@module("react-dom/test-utils")
external reactAct: ((. unit) => undefined) => unit = "act"
external reactAct: ((. ()) => undefined) => unit = "act"

let act: (unit => unit) => unit = func => {
let reactFunc = (. ()) => {
Expand All @@ -14,7 +14,7 @@ let act: (unit => unit) => unit = func => {
}

@module("react-dom/test-utils")
external reactActAsync: ((. unit) => Js.Promise.t<'a>) => Js.Promise.t<unit> = "act"
external reactActAsync: ((. ()) => Js.Promise.t<'a>) => Js.Promise.t<unit> = "act"

let actAsync = func => {
let reactFunc = (. ()) => func()
Expand Down
5 changes: 3 additions & 2 deletions lib/4.06.1/unstable/js_compiler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54752,9 +54752,10 @@ and printTypExpr ~state (typExpr : Parsetree.core_type) cmtTbl =
| Ptyp_object (fields, openFlag) ->
printObject ~state ~inline:false fields openFlag cmtTbl
| Ptyp_arrow _ -> printArrow ~uncurried:false typExpr
| Ptyp_constr ({txt = Lident "()"}, []) -> Doc.text "()"
| Ptyp_constr ({txt = Ldot (Ldot (Lident "Js", "Fn"), "arity0")}, [tArg]) ->
let unitConstr = Location.mkloc (Longident.Lident "unit") tArg.ptyp_loc in
let tUnit = Ast_helper.Typ.constr unitConstr [] in
let parensConstr = Location.mkloc (Longident.Lident "()") tArg.ptyp_loc in
let tUnit = Ast_helper.Typ.constr parensConstr [] in
printArrow ~uncurried:true ~arity:1
{tArg with ptyp_desc = Ptyp_arrow (Nolabel, tUnit, tArg)}
| Ptyp_constr ({txt = Ldot (Ldot (Lident "Js", "Fn"), arity)}, [tArg])
Expand Down
12 changes: 7 additions & 5 deletions lib/4.06.1/unstable/js_playground_compiler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54752,9 +54752,10 @@ and printTypExpr ~state (typExpr : Parsetree.core_type) cmtTbl =
| Ptyp_object (fields, openFlag) ->
printObject ~state ~inline:false fields openFlag cmtTbl
| Ptyp_arrow _ -> printArrow ~uncurried:false typExpr
| Ptyp_constr ({txt = Lident "()"}, []) -> Doc.text "()"
| Ptyp_constr ({txt = Ldot (Ldot (Lident "Js", "Fn"), "arity0")}, [tArg]) ->
let unitConstr = Location.mkloc (Longident.Lident "unit") tArg.ptyp_loc in
let tUnit = Ast_helper.Typ.constr unitConstr [] in
let parensConstr = Location.mkloc (Longident.Lident "()") tArg.ptyp_loc in
let tUnit = Ast_helper.Typ.constr parensConstr [] in
printArrow ~uncurried:true ~arity:1
{tArg with ptyp_desc = Ptyp_arrow (Nolabel, tUnit, tArg)}
| Ptyp_constr ({txt = Ldot (Ldot (Lident "Js", "Fn"), arity)}, [tArg])
Expand Down Expand Up @@ -166636,14 +166637,15 @@ and parseEs6ArrowType ~attrs p =
if p.uncurried_by_default then not dotted else dotted
in
if uncurried && (paramNum = 1 || not p.uncurried_by_default) then
let isUnit =
let isParens =
match typ.ptyp_desc with
| Ptyp_constr ({txt = Lident "unit"}, []) -> true
| Ptyp_constr ({txt = Lident "unit"; loc}, []) ->
loc.loc_end.pos_cnum - loc.loc_start.pos_cnum = 2 (* () *)
| _ -> false
in
let loc = mkLoc startPos endPos in
let fnArity, tArg =
if isUnit && arity = 1 then (0, t)
if isParens && arity = 1 then (0, t)
else (arity, Ast_helper.Typ.arrow ~loc ~attrs argLbl typ t)
in
( paramNum - 1,
Expand Down
12 changes: 7 additions & 5 deletions lib/4.06.1/whole_compiler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -109750,9 +109750,10 @@ and printTypExpr ~state (typExpr : Parsetree.core_type) cmtTbl =
| Ptyp_object (fields, openFlag) ->
printObject ~state ~inline:false fields openFlag cmtTbl
| Ptyp_arrow _ -> printArrow ~uncurried:false typExpr
| Ptyp_constr ({txt = Lident "()"}, []) -> Doc.text "()"
| Ptyp_constr ({txt = Ldot (Ldot (Lident "Js", "Fn"), "arity0")}, [tArg]) ->
let unitConstr = Location.mkloc (Longident.Lident "unit") tArg.ptyp_loc in
let tUnit = Ast_helper.Typ.constr unitConstr [] in
let parensConstr = Location.mkloc (Longident.Lident "()") tArg.ptyp_loc in
let tUnit = Ast_helper.Typ.constr parensConstr [] in
printArrow ~uncurried:true ~arity:1
{tArg with ptyp_desc = Ptyp_arrow (Nolabel, tUnit, tArg)}
| Ptyp_constr ({txt = Ldot (Ldot (Lident "Js", "Fn"), arity)}, [tArg])
Expand Down Expand Up @@ -180068,14 +180069,15 @@ and parseEs6ArrowType ~attrs p =
if p.uncurried_by_default then not dotted else dotted
in
if uncurried && (paramNum = 1 || not p.uncurried_by_default) then
let isUnit =
let isParens =
match typ.ptyp_desc with
| Ptyp_constr ({txt = Lident "unit"}, []) -> true
| Ptyp_constr ({txt = Lident "unit"; loc}, []) ->
loc.loc_end.pos_cnum - loc.loc_start.pos_cnum = 2 (* () *)
| _ -> false
in
let loc = mkLoc startPos endPos in
let fnArity, tArg =
if isUnit && arity = 1 then (0, t)
if isParens && arity = 1 then (0, t)
else (arity, Ast_helper.Typ.arrow ~loc ~attrs argLbl typ t)
in
( paramNum - 1,
Expand Down
7 changes: 4 additions & 3 deletions res_syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4250,14 +4250,15 @@ and parseEs6ArrowType ~attrs p =
if p.uncurried_by_default then not dotted else dotted
in
if uncurried && (paramNum = 1 || not p.uncurried_by_default) then
let isUnit =
let isParens =
match typ.ptyp_desc with
| Ptyp_constr ({txt = Lident "unit"}, []) -> true
| Ptyp_constr ({txt = Lident "unit"; loc}, []) ->
loc.loc_end.pos_cnum - loc.loc_start.pos_cnum = 2 (* () *)
| _ -> false
in
let loc = mkLoc startPos endPos in
let fnArity, tArg =
if isUnit && arity = 1 then (0, t)
if isParens && arity = 1 then (0, t)
else (arity, Ast_helper.Typ.arrow ~loc ~attrs argLbl typ t)
in
( paramNum - 1,
Expand Down
5 changes: 3 additions & 2 deletions res_syntax/src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1653,9 +1653,10 @@ and printTypExpr ~state (typExpr : Parsetree.core_type) cmtTbl =
| Ptyp_object (fields, openFlag) ->
printObject ~state ~inline:false fields openFlag cmtTbl
| Ptyp_arrow _ -> printArrow ~uncurried:false typExpr
| Ptyp_constr ({txt = Lident "()"}, []) -> Doc.text "()"
| Ptyp_constr ({txt = Ldot (Ldot (Lident "Js", "Fn"), "arity0")}, [tArg]) ->
let unitConstr = Location.mkloc (Longident.Lident "unit") tArg.ptyp_loc in
let tUnit = Ast_helper.Typ.constr unitConstr [] in
let parensConstr = Location.mkloc (Longident.Lident "()") tArg.ptyp_loc in
let tUnit = Ast_helper.Typ.constr parensConstr [] in
printArrow ~uncurried:true ~arity:1
{tArg with ptyp_desc = Ptyp_arrow (Nolabel, tUnit, tArg)}
| Ptyp_constr ({txt = Ldot (Ldot (Lident "Js", "Fn"), arity)}, [tArg])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ type mixTyp = (string, .string, string) => (string, string, string) => (string,
type bTyp = (. string) => string => int
type cTyp2 = (string, string) => int
type uTyp2 = (.string, string) => int
type cu = unit => int
type cp = () => int
type cuu = unit => unit => int
type cpu = () => unit => int
type cup = unit => () => int
type cpp = () => () => int
type cu2 = (unit, unit) => unit
type cp2 = ((), ()) => unit
type uu = (. unit) => int
type up = (. ()) => int
type uuu = (. unit) => (. unit) => int
type upu = (. ()) => (. unit) => int
type uup = (. unit) => (. ()) => int
type upp = (. ()) => (. ()) => int
type uu2 = (. unit, unit) => unit
type up2 = (. (), ()) => unit

@@uncurried

Expand All @@ -34,5 +50,21 @@ type mixTyp = (.string) => (string, string) => (.string, string, string, string)
type bTyp = string => (. string) => int
type cTyp2 = (.string, string) => int
type uTyp2 = (string, string) => int
type cu = (. unit) => int
type cp = (. ()) => int
type cuu = (. unit) => (. unit) => int
type cpu = (. ()) => (. unit) => int
type cup = (. unit) => (. ()) => int
type cpp = (. ()) => (. ()) => int
type cu2 = (. unit, unit) => unit
type cp2 = (. (), ()) => unit
type uu = unit => int
type up = () => int
type uuu = unit => unit => int
type upu = () => unit => int
type uup = unit => () => int
type upp = () => () => int
type uu2 = (unit, unit) => unit
type up2 = ((), ()) => unit

let pipe1 = 3->f
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ type nonrec mixTyp =
type nonrec bTyp = (string -> string -> int) Js.Fn.arity1
type nonrec cTyp2 = string -> string -> int
type nonrec uTyp2 = (string -> string -> int) Js.Fn.arity2
type nonrec cu = unit -> int
type nonrec cp = unit -> int
type nonrec cuu = unit -> unit -> int
type nonrec cpu = unit -> unit -> int
type nonrec cup = unit -> unit -> int
type nonrec cpp = unit -> unit -> int
type nonrec cu2 = unit -> unit -> unit
type nonrec cp2 = unit -> unit -> unit
type nonrec uu = (unit -> int) Js.Fn.arity1
type nonrec up = int Js.Fn.arity0
type nonrec uuu = (unit -> (unit -> int) Js.Fn.arity1) Js.Fn.arity1
type nonrec upu = (unit -> int) Js.Fn.arity1 Js.Fn.arity0
type nonrec uup = (unit -> int Js.Fn.arity0) Js.Fn.arity1
type nonrec upp = int Js.Fn.arity0 Js.Fn.arity0
type nonrec uu2 = (unit -> unit -> unit) Js.Fn.arity2
type nonrec up2 = (unit -> unit -> unit) Js.Fn.arity2
[@@@uncurried ]
let cApp = foo 3
let uApp = ((foo 3)[@bs ])
Expand Down Expand Up @@ -52,4 +68,20 @@ type nonrec mixTyp =
type nonrec bTyp = (string -> string -> int) Js.Fn.arity1
type nonrec cTyp2 = string -> string -> int
type nonrec uTyp2 = (string -> string -> int) Js.Fn.arity2
type nonrec cu = unit -> int
type nonrec cp = unit -> int
type nonrec cuu = unit -> unit -> int
type nonrec cpu = unit -> unit -> int
type nonrec cup = unit -> unit -> int
type nonrec cpp = unit -> unit -> int
type nonrec cu2 = unit -> unit -> unit
type nonrec cp2 = unit -> unit -> unit
type nonrec uu = (unit -> int) Js.Fn.arity1
type nonrec up = int Js.Fn.arity0
type nonrec uuu = (unit -> (unit -> int) Js.Fn.arity1) Js.Fn.arity1
type nonrec upu = (unit -> int) Js.Fn.arity1 Js.Fn.arity0
type nonrec uup = (unit -> int Js.Fn.arity0) Js.Fn.arity1
type nonrec upp = int Js.Fn.arity0 Js.Fn.arity0
type nonrec uu2 = (unit -> unit -> unit) Js.Fn.arity2
type nonrec up2 = (unit -> unit -> unit) Js.Fn.arity2
let pipe1 = 3 |.u f
2 changes: 1 addition & 1 deletion res_syntax/tests/parsing/grammar/typexpr/uncurried.res
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ type t = @attr (. float) => @attr2 int => @attr3 (. bool) => @attr4 string => un
type t = (. (@attr float), (@attr2 int), . (@attr3 bool), (@attr4 string)) => unit

@bs.val
external setTimeout : ((. unit) => unit, int) => timerId = "setTimeout"
external setTimeout : ((. ()) => unit, int) => timerId = "setTimeout"
// totally different meaning
external setTimeout : (. unit => unit, int) => timerId = "setTimeout"
32 changes: 32 additions & 0 deletions res_syntax/tests/printer/expr/UncurriedByDefault.res
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ type mixTyp = (string, .string, string) => (string, string, string) => (string,
type bTyp = (. string) => string => int
type cTyp2 = (string, string) => int
type uTyp2 = (.string, string) => int
type cu = unit => int
type cp = () => int
type cuu = unit => unit => int
type cpu = () => unit => int
type cup = unit => () => int
type cpp = () => () => int
type cu2 = (unit, unit) => unit
type cp2 = ((), ()) => unit
type uu = (. unit) => int
type up = (. ()) => int
type uuu = (. unit) => (. unit) => int
type upu = (. ()) => (. unit) => int
type uup = (. unit) => (. ()) => int
type upp = (. ()) => (. ()) => int
type uu2 = (. unit, unit) => unit
type up2 = (. (), ()) => unit

let pipe = a->foo(. b, c)

Expand All @@ -36,5 +52,21 @@ type mixTyp = (.string) => (string, string) => (.string, string, string, string)
type bTyp = string => (. string) => int
type cTyp2 = (. string, string) => int
type uTyp2 = (string, string) => int
type cu = (. unit) => int
type cp = (. ()) => int
type cuu = (. unit) => (. unit) => int
type cpu = (. ()) => (. unit) => int
type cup = (. unit) => (. ()) => int
type cpp = (. ()) => (. ()) => int
type cu2 = (. unit, unit) => unit
type cp2 = (. (), ()) => unit
type uu = unit => int
type up = () => int
type uuu = unit => unit => int
type upu = () => unit => int
type uup = unit => () => int
type upp = () => () => int
type uu2 = (unit, unit) => unit
type up2 = ((), ()) => unit

let pipe = a->foo(b, c)
32 changes: 32 additions & 0 deletions res_syntax/tests/printer/expr/expected/UncurriedByDefault.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ type mixTyp = string => (. string, string) => (string, string, string, string) =
type bTyp = (. string) => string => int
type cTyp2 = (string, string) => int
type uTyp2 = (. string, string) => int
type cu = unit => int
type cp = unit => int
type cuu = (unit, unit) => int
type cpu = (unit, unit) => int
type cup = (unit, unit) => int
type cpp = (unit, unit) => int
type cu2 = (unit, unit) => unit
type cp2 = (unit, unit) => unit
type uu = (. unit) => int
type up = (. ()) => int
type uuu = (. unit) => (. unit) => int
type upu = (. ()) => (. unit) => int
type uup = (. unit) => (. ()) => int
type upp = (. ()) => (. ()) => int
type uu2 = (. unit, unit) => unit
type up2 = (. unit, unit) => unit

let pipe = a->foo(. b, c)

Expand All @@ -36,5 +52,21 @@ type mixTyp = (. string) => (string, string) => (. string, string, string, strin
type bTyp = string => (. string) => int
type cTyp2 = (. string, string) => int
type uTyp2 = (string, string) => int
type cu = (. unit) => int
type cp = (. unit) => int
type cuu = (. unit, unit) => int
type cpu = (. unit, unit) => int
type cup = (. unit, unit) => int
type cpp = (. unit, unit) => int
type cu2 = (. unit, unit) => unit
type cp2 = (. unit, unit) => unit
type uu = unit => int
type up = () => int
type uuu = unit => unit => int
type upu = () => unit => int
type uup = unit => () => int
type upp = () => () => int
type uu2 = (unit, unit) => unit
type up2 = (unit, unit) => unit

let pipe = a->foo(b, c)