Skip to content

Commit 2ad77e5

Browse files
authored
Fix deriving accessors in uncurried mode (#6687)
* Implement handle uncurried in deriving accessors * Handle variants with no parameters in transform and move build tests * Add deriving accessors fix to the changelog
1 parent c03abaa commit 2ad77e5

8 files changed

+243
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#### :bug: Bug Fix
1616

1717
- Fix misparsing in/after JSX. https://github.com/rescript-lang/rescript-compiler/pull/6686
18+
- Fix `@deriving(accessors)` outputting curried functions in uncurried mode https://github.com/rescript-lang/rescript-compiler/pull/6687
1819

1920
# 11.1.0-rc.4
2021

jscomp/frontend/ast_derive_projector.ml

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ let init () =
1414
{
1515
structure_gen =
1616
(fun (tdcls : tdcls) _explict_nonrec ->
17+
let handle_uncurried_accessor_tranform ~loc ~arity accessor =
18+
(* Accessors with no params (arity of 0) are simply values and not functions *)
19+
match Config.uncurried.contents with
20+
| Uncurried when arity > 0 ->
21+
Ast_uncurried.uncurriedFun ~loc ~arity accessor
22+
| _ -> accessor
23+
in
1724
let handle_tdcl tdcl =
1825
let core_type =
1926
Ast_derive_util.core_type_of_type_declaration tdcl
@@ -39,7 +46,9 @@ let init () =
3946
(Pat.constraint_ (Pat.var {txt; loc}) core_type)
4047
(Exp.field
4148
(Exp.ident {txt = Lident txt; loc})
42-
{txt = Longident.Lident pld_label; loc})))
49+
{txt = Longident.Lident pld_label; loc})
50+
(*arity will alwys be 1 since these are single param functions*)
51+
|> handle_uncurried_accessor_tranform ~arity:1 ~loc))
4352
| Ptype_variant constructor_declarations ->
4453
Ext_list.map constructor_declarations
4554
(fun
@@ -94,7 +103,8 @@ let init () =
94103
annotate_type
95104
in
96105
Ext_list.fold_right vars exp (fun var b ->
97-
Ast_compatible.fun_ (Pat.var {loc; txt = var}) b)))
106+
Ast_compatible.fun_ (Pat.var {loc; txt = var}) b)
107+
|> handle_uncurried_accessor_tranform ~loc ~arity))
98108
| Ptype_abstract | Ptype_open ->
99109
Ast_derive_util.notApplicable tdcl.ptype_loc derivingName;
100110
[]
@@ -103,6 +113,13 @@ let init () =
103113
Ext_list.flat_map tdcls handle_tdcl);
104114
signature_gen =
105115
(fun (tdcls : Parsetree.type_declaration list) _explict_nonrec ->
116+
let handle_uncurried_type_tranform ~loc ~arity t =
117+
match Config.uncurried.contents with
118+
(* Accessors with no params (arity of 0) are simply values and not functions *)
119+
| Uncurried when arity > 0 ->
120+
Ast_uncurried.uncurriedType ~loc ~arity t
121+
| _ -> t
122+
in
106123
let handle_tdcl tdcl =
107124
let core_type =
108125
Ast_derive_util.core_type_of_type_declaration tdcl
@@ -119,7 +136,10 @@ let init () =
119136
| Ptype_record label_declarations ->
120137
Ext_list.map label_declarations (fun {pld_name; pld_type} ->
121138
Ast_comb.single_non_rec_val ?attrs:gentype_attrs pld_name
122-
(Ast_compatible.arrow core_type pld_type))
139+
(Ast_compatible.arrow core_type pld_type
140+
(*arity will alwys be 1 since these are single param functions*)
141+
|> handle_uncurried_type_tranform ~arity:1
142+
~loc:pld_name.loc))
123143
| Ptype_variant constructor_declarations ->
124144
Ext_list.map constructor_declarations
125145
(fun
@@ -135,6 +155,7 @@ let init () =
135155
| Pcstr_tuple pcd_args -> pcd_args
136156
| Pcstr_record _ -> assert false
137157
in
158+
let arity = pcd_args |> List.length in
138159
let annotate_type =
139160
match pcd_res with
140161
| Some x -> x
@@ -143,7 +164,8 @@ let init () =
143164
Ast_comb.single_non_rec_val ?attrs:gentype_attrs
144165
{loc; txt = Ext_string.uncapitalize_ascii con_name}
145166
(Ext_list.fold_right pcd_args annotate_type (fun x acc ->
146-
Ast_compatible.arrow x acc)))
167+
Ast_compatible.arrow x acc)
168+
|> handle_uncurried_type_tranform ~arity ~loc))
147169
| Ptype_open | Ptype_abstract ->
148170
Ast_derive_util.notApplicable tdcl.ptype_loc derivingName;
149171
[]

jscomp/test/DerivingAccessorsCurried.js

Lines changed: 57 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//Assert that deriving accessors does not break
2+
//In curried mode
3+
4+
@deriving(accessors)
5+
type myRecord = { myField: int }
6+
7+
@deriving(accessors)
8+
type variant = | NoParam | Num(int) | DoubleNum(int, int)
9+
10+
//Asserts the correct signature for derived accessor
11+
let _myFieldAlias: myRecord => int = myField
12+
let _noParamAlias: variant = noParam
13+
let _numAlias: int => variant = num
14+
let _doubleNumAlias: (int, int) => variant = doubleNum
15+
16+
//Asserts that inference works when composing
17+
//with derived functions
18+
let compose = (a, accessor) => accessor(a)
19+
let _composedMyField = compose({ myField: 1 }, myField)
20+
let _composedNum = compose(1, num)
21+

jscomp/test/DerivingAccessorsUncurried.js

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//Assert that deriving accessors does not break
2+
//In uncurried mode
3+
@@uncurried
4+
5+
@deriving(accessors)
6+
type myRecord = { myField: int }
7+
8+
@deriving(accessors)
9+
type variant = | NoParam | Num(int) | DoubleNum(int, int)
10+
11+
//Asserts the correct signature for derived accessor
12+
let _myFieldAlias: myRecord => int = myField
13+
let _noParamAlias: variant = noParam
14+
let _numAlias: int => variant = num
15+
let _doubleNumAlias: (int, int) => variant = doubleNum
16+
17+
//Asserts that inference works when composing
18+
//with derived functions
19+
let compose = (a, accessor) => accessor(a)
20+
let _composedMyField = compose({ myField: 1 }, myField)
21+
let _composedNum = compose(1, num)
22+

jscomp/test/DerivingAccessorsUnurried.js

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

jscomp/test/build.ninja

Lines changed: 3 additions & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)