Skip to content

Fix deriving accessors in uncurried mode #6687

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
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 @@ -15,6 +15,7 @@
#### :bug: Bug Fix

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

# 11.1.0-rc.4

Expand Down
30 changes: 26 additions & 4 deletions jscomp/frontend/ast_derive_projector.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ let init () =
{
structure_gen =
(fun (tdcls : tdcls) _explict_nonrec ->
let handle_uncurried_accessor_tranform ~loc ~arity accessor =
(* Accessors with no params (arity of 0) are simply values and not functions *)
match Config.uncurried.contents with
| Uncurried when arity > 0 ->
Ast_uncurried.uncurriedFun ~loc ~arity accessor
| _ -> accessor
in
let handle_tdcl tdcl =
let core_type =
Ast_derive_util.core_type_of_type_declaration tdcl
Expand All @@ -39,7 +46,9 @@ let init () =
(Pat.constraint_ (Pat.var {txt; loc}) core_type)
(Exp.field
(Exp.ident {txt = Lident txt; loc})
{txt = Longident.Lident pld_label; loc})))
{txt = Longident.Lident pld_label; loc})
(*arity will alwys be 1 since these are single param functions*)
|> handle_uncurried_accessor_tranform ~arity:1 ~loc))
| Ptype_variant constructor_declarations ->
Ext_list.map constructor_declarations
(fun
Expand Down Expand Up @@ -94,7 +103,8 @@ let init () =
annotate_type
in
Ext_list.fold_right vars exp (fun var b ->
Ast_compatible.fun_ (Pat.var {loc; txt = var}) b)))
Ast_compatible.fun_ (Pat.var {loc; txt = var}) b)
|> handle_uncurried_accessor_tranform ~loc ~arity))
| Ptype_abstract | Ptype_open ->
Ast_derive_util.notApplicable tdcl.ptype_loc derivingName;
[]
Expand All @@ -103,6 +113,13 @@ let init () =
Ext_list.flat_map tdcls handle_tdcl);
signature_gen =
(fun (tdcls : Parsetree.type_declaration list) _explict_nonrec ->
let handle_uncurried_type_tranform ~loc ~arity t =
match Config.uncurried.contents with
(* Accessors with no params (arity of 0) are simply values and not functions *)
| Uncurried when arity > 0 ->
Ast_uncurried.uncurriedType ~loc ~arity t
| _ -> t
in
let handle_tdcl tdcl =
let core_type =
Ast_derive_util.core_type_of_type_declaration tdcl
Expand All @@ -119,7 +136,10 @@ let init () =
| Ptype_record label_declarations ->
Ext_list.map label_declarations (fun {pld_name; pld_type} ->
Ast_comb.single_non_rec_val ?attrs:gentype_attrs pld_name
(Ast_compatible.arrow core_type pld_type))
(Ast_compatible.arrow core_type pld_type
(*arity will alwys be 1 since these are single param functions*)
|> handle_uncurried_type_tranform ~arity:1
~loc:pld_name.loc))
| Ptype_variant constructor_declarations ->
Ext_list.map constructor_declarations
(fun
Expand All @@ -135,6 +155,7 @@ let init () =
| Pcstr_tuple pcd_args -> pcd_args
| Pcstr_record _ -> assert false
in
let arity = pcd_args |> List.length in
let annotate_type =
match pcd_res with
| Some x -> x
Expand All @@ -143,7 +164,8 @@ let init () =
Ast_comb.single_non_rec_val ?attrs:gentype_attrs
{loc; txt = Ext_string.uncapitalize_ascii con_name}
(Ext_list.fold_right pcd_args annotate_type (fun x acc ->
Ast_compatible.arrow x acc)))
Ast_compatible.arrow x acc)
|> handle_uncurried_type_tranform ~arity ~loc))
| Ptype_open | Ptype_abstract ->
Ast_derive_util.notApplicable tdcl.ptype_loc derivingName;
[]
Expand Down
57 changes: 57 additions & 0 deletions jscomp/test/DerivingAccessorsCurried.js

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

21 changes: 21 additions & 0 deletions jscomp/test/DerivingAccessorsCurried.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//Assert that deriving accessors does not break
//In curried mode

@deriving(accessors)
type myRecord = { myField: int }

@deriving(accessors)
type variant = | NoParam | Num(int) | DoubleNum(int, int)

//Asserts the correct signature for derived accessor
let _myFieldAlias: myRecord => int = myField
let _noParamAlias: variant = noParam
let _numAlias: int => variant = num
let _doubleNumAlias: (int, int) => variant = doubleNum

//Asserts that inference works when composing
//with derived functions
let compose = (a, accessor) => accessor(a)
let _composedMyField = compose({ myField: 1 }, myField)
let _composedNum = compose(1, num)

56 changes: 56 additions & 0 deletions jscomp/test/DerivingAccessorsUncurried.js

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

22 changes: 22 additions & 0 deletions jscomp/test/DerivingAccessorsUncurried.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//Assert that deriving accessors does not break
//In uncurried mode
@@uncurried

@deriving(accessors)
type myRecord = { myField: int }

@deriving(accessors)
type variant = | NoParam | Num(int) | DoubleNum(int, int)

//Asserts the correct signature for derived accessor
let _myFieldAlias: myRecord => int = myField
let _noParamAlias: variant = noParam
let _numAlias: int => variant = num
let _doubleNumAlias: (int, int) => variant = doubleNum

//Asserts that inference works when composing
//with derived functions
let compose = (a, accessor) => accessor(a)
let _composedMyField = compose({ myField: 1 }, myField)
let _composedNum = compose(1, num)

57 changes: 57 additions & 0 deletions jscomp/test/DerivingAccessorsUnurried.js

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

4 changes: 3 additions & 1 deletion jscomp/test/build.ninja

Large diffs are not rendered by default.