Skip to content

Commit f1a7cb0

Browse files
committed
Gentype: fix issue with labelled args which should not be grouped.
Grouping labelled args is a leftover incompatible with zero cost conversion. Fixes #6361
1 parent 5f1d839 commit f1a7cb0

19 files changed

+70
-112
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
1313
# 11.0.0-rc.4 (Unreleased)
1414

15+
#### :bug: Bug Fix
16+
17+
- Fix issue with GenType and labelled arguments https://github.com/rescript-lang/rescript-compiler/pull/6406
18+
1519
#### :rocket: New Feature
1620

1721
- Support renaming fields in inline records with `@as` attribute. [#6391](https://github.com/rescript-lang/rescript-compiler/pull/6391)

jscomp/gentype/Converter.ml

+2-18
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ let typeGetInlined ~config ~lookupId ~typeNameIsInterface type0 =
1313
let argConverted = argTypes |> List.map (argTypeToGroupedArg ~visited) in
1414
let retNormalized = retType |> visit ~visited in
1515
Function {function_ with argTypes = argConverted; retType = retNormalized}
16-
| GroupOfLabeledArgs _ ->
17-
(* This case should only fire from withing a function *)
18-
normalized_
1916
| Ident {builtin = true} -> normalized_
2017
| Ident {builtin = false; name; typeArgs} -> (
2118
if visited |> StringSet.mem name then (
@@ -77,21 +74,8 @@ let typeGetInlined ~config ~lookupId ~typeNameIsInterface type0 =
7774
in
7875
normalized
7976
and argTypeToGroupedArg ~visited {aName; aType} =
80-
match aType with
81-
| GroupOfLabeledArgs fields ->
82-
let fieldsConverted =
83-
fields
84-
|> List.map (fun ({type_} as field) -> (field, type_ |> visit ~visited))
85-
in
86-
let tNormalized =
87-
GroupOfLabeledArgs
88-
(fieldsConverted
89-
|> List.map (fun (field, t) -> {field with type_ = t}))
90-
in
91-
{aName; aType = tNormalized}
92-
| _ ->
93-
let tNormalized = aType |> visit ~visited in
94-
{aName; aType = tNormalized}
77+
let tNormalized = aType |> visit ~visited in
78+
{aName; aType = tNormalized}
9579
in
9680
let normalized = type0 |> visit ~visited:StringSet.empty in
9781
if !Debug.converter then

jscomp/gentype/EmitJs.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ let propagateAnnotationToSubTypes ~codeItems (typeMap : CodeItem.exportTypeMap)
549549
| Function {argTypes; retType} ->
550550
argTypes |> List.iter (fun {aType} -> visit aType);
551551
retType |> visit
552-
| GroupOfLabeledArgs fields | Object (_, fields) ->
552+
| Object (_, fields) ->
553553
fields |> List.iter (fun {type_} -> type_ |> visit)
554554
| Option t | Null t | Nullable t | Promise t -> t |> visit
555555
| Tuple innerTypes -> innerTypes |> List.iter visit

jscomp/gentype/EmitType.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ let rec renderType ~(config : Config.t) ?(indent = None) ~typeNameIsInterface
105105
| Function {argTypes; retType; typeVars} ->
106106
renderFunType ~config ~indent ~inFunType ~typeNameIsInterface ~typeVars
107107
argTypes retType
108-
| GroupOfLabeledArgs fields | Object (_, fields) ->
108+
| Object (_, fields) ->
109109
let indent1 = fields |> Indent.heuristicFields ~indent in
110110
fields
111111
|> renderFields ~config ~indent:indent1 ~inFunType ~typeNameIsInterface

jscomp/gentype/GenTypeCommon.ml

-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ type type_ =
6969
| Array of type_ * mutable_
7070
| Dict of type_
7171
| Function of function_
72-
| GroupOfLabeledArgs of fields
7372
| Ident of ident
7473
| Null of type_
7574
| Nullable of type_

jscomp/gentype/NamedArgs.ml

+14-59
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,17 @@
11
open GenTypeCommon
22

3-
type groupedArg = Group of fields | Arg of type_
4-
5-
(**
6-
For convenient processing turns consecutive named arguments into a
7-
`NamedArgs` group, and individual non-named arguments into `Arg`s.
8-
*)
9-
let rec groupReversed ~revCurGroup ~revResult labeledTypes =
10-
match (revCurGroup, labeledTypes) with
11-
| [], (Nolabel, type_) :: tl ->
12-
groupReversed ~revCurGroup:[] ~revResult:(Arg type_ :: revResult) tl
13-
| _, (OptLabel name, type_) :: tl ->
14-
(* Add it to the current group, not result. *)
15-
groupReversed
16-
~revCurGroup:
17-
({
18-
mutable_ = Immutable;
19-
nameJS = name;
20-
optional = Optional;
21-
type_;
22-
docString = DocString.empty;
23-
}
24-
:: revCurGroup)
25-
~revResult tl
26-
| _, (Label name, type_) :: tl ->
27-
groupReversed
28-
~revCurGroup:
29-
({
30-
mutable_ = Immutable;
31-
nameJS = name;
32-
optional = Mandatory;
33-
type_;
34-
docString = DocString.empty;
35-
}
36-
:: revCurGroup)
37-
~revResult tl
38-
| [], [] -> revResult
39-
| _grpHd :: _grpTl, ([] as _tl) | _grpHd :: _grpTl, (Nolabel, _) :: _tl ->
40-
(* Just form the group, and recurse ignoring the (None, t) in that case.
41-
t will be handled in recursion. *)
42-
groupReversed ~revCurGroup:[]
43-
~revResult:(Group revCurGroup :: revResult)
44-
labeledTypes
45-
46-
(** Special reverse that not only reverses the entire list but also the order of
47-
items in the NamedArgs grouping. *)
48-
let rec reverse ?(soFar = []) lst =
49-
match lst with
50-
| [] -> soFar
51-
| [Arg type_] when type_ = unitT && soFar = [] ->
52-
(* treat a single argument of type unit as no argument *)
53-
[]
54-
| Arg type_ :: tl -> reverse ~soFar:({aName = ""; aType = type_} :: soFar) tl
55-
| Group fields :: tl ->
56-
reverse
57-
~soFar:
58-
({aName = ""; aType = GroupOfLabeledArgs (List.rev fields)} :: soFar)
59-
tl
60-
613
let group labeledTypes =
62-
labeledTypes |> groupReversed ~revCurGroup:[] ~revResult:[] |> reverse
4+
let types =
5+
Ext_list.map labeledTypes (fun (lbl, type_) ->
6+
let aName =
7+
match lbl with
8+
| Nolabel -> ""
9+
| Label lbl | OptLabel lbl -> lbl
10+
in
11+
12+
{aName; aType = type_})
13+
in
14+
match types with
15+
| [{aType}] when aType = unitT ->
16+
[] (* treat a single argument of type unit as no argument *)
17+
| _ -> types

jscomp/gentype/TranslateStructure.ml

+11-6
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@ open GenTypeCommon
33
let rec addAnnotationsToTypes_ ~config ~(expr : Typedtree.expression)
44
(argTypes : argType list) =
55
match (expr.exp_desc, expr.exp_type.desc, argTypes) with
6-
| _, _, {aName; aType = GroupOfLabeledArgs fields} :: nextTypes ->
7-
let fields1, nextTypes1 =
8-
addAnnotationsToFields ~config expr fields nextTypes
9-
in
10-
{aName; aType = GroupOfLabeledArgs fields1} :: nextTypes1
11-
| Texp_function {param; cases = [{c_rhs}]}, _, {aType} :: nextTypes ->
6+
| Texp_function {arg_label; param; cases = [{c_rhs}]}, _, {aType} :: nextTypes
7+
->
128
let nextTypes1 = nextTypes |> addAnnotationsToTypes_ ~config ~expr:c_rhs in
139
let aName = Ident.name param in
10+
let _ = Printtyped.implementation in
11+
let aName =
12+
if aName = "*opt*" then
13+
match arg_label with
14+
| Optional l ->
15+
l
16+
| _ -> "" (* should not happen *)
17+
else aName
18+
in
1419
{aName; aType} :: nextTypes1
1520
| Texp_construct ({txt = Lident "Function$"}, _, [funExpr]), _, _ ->
1621
(* let uncurried1: function$<_, _> = Function$(x => x |> string_of_int, [`Has_arity1]) *)

jscomp/gentype/TypeVars.ml

+1-6
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ let rec substitute ~f type0 =
4040
|> List.map (fun {aName; aType = t} ->
4141
{aName; aType = t |> substitute ~f});
4242
}
43-
| GroupOfLabeledArgs fields ->
44-
GroupOfLabeledArgs
45-
(fields
46-
|> List.map (fun field ->
47-
{field with type_ = field.type_ |> substitute ~f}))
4843
| Ident {typeArgs = []} -> type0
4944
| Ident ({typeArgs} as ident) ->
5045
Ident {ident with typeArgs = typeArgs |> List.map (substitute ~f)}
@@ -80,7 +75,7 @@ let rec free_ type0 : StringSet.t =
8075
StringSet.diff
8176
((argTypes |> freeOfList_) +++ (retType |> free_))
8277
(typeVars |> StringSet.of_list)
83-
| GroupOfLabeledArgs fields | Object (_, fields) ->
78+
| Object (_, fields) ->
8479
fields
8580
|> List.fold_left
8681
(fun s {type_} -> StringSet.union s (type_ |> free_))

jscomp/gentype_tests/typescript-react-example/package-lock.json

+4-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/gentype_tests/typescript-react-example/src/Docstrings.gen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const unnamed2: (param_0:number, param_1:number) => number = DocstringsBS
3939

4040
export const unnamed2U: (param_0:number, param_1:number) => number = DocstringsBS.unnamed2U;
4141

42-
export const grouped: (_1:{ readonly x: number; readonly y: number }, a:number, b:number, c:number, _5:{ readonly z: number }) => number = DocstringsBS.grouped;
42+
export const grouped: (x:number, y:number, a:number, b:number, c:number, z:number) => number = DocstringsBS.grouped;
4343

4444
export const unitArgWithoutConversion: () => string = DocstringsBS.unitArgWithoutConversion;
4545

jscomp/gentype_tests/typescript-react-example/src/Hooks.gen.tsx

+2-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type {TypedArray2_Uint8Array_t as Js_TypedArray2_Uint8Array_t} from '../s
1414
export type vehicle = { readonly name: string };
1515

1616
// tslint:disable-next-line:interface-over-type-literal
17-
export type cb = (_1:{ readonly _to: vehicle }) => void;
17+
export type cb = (_to:vehicle) => void;
1818

1919
// tslint:disable-next-line:interface-over-type-literal
2020
export type r = { readonly x: string };
@@ -71,11 +71,7 @@ export type NoProps_make_Props = {};
7171

7272
export const NoProps_make: React.ComponentType<{}> = HooksBS.NoProps.make;
7373

74-
export const functionWithRenamedArgs: (_1:{
75-
readonly _to: vehicle;
76-
readonly _Type: vehicle;
77-
readonly cb: cb
78-
}) => string = HooksBS.functionWithRenamedArgs;
74+
export const functionWithRenamedArgs: (_to:vehicle, _Type:vehicle, cb:cb) => string = HooksBS.functionWithRenamedArgs;
7975

8076
// tslint:disable-next-line:interface-over-type-literal
8177
export type WithRename_componentWithRenamedArgs_Props = {

jscomp/gentype_tests/typescript-react-example/src/ImportHooks.gen.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ export const makeRenamed: unknown = makeRenamedTypeChecked as React.ComponentTyp
2323
}>;
2424

2525
// In case of type error, check the type of 'foo' in 'ImportHooks.res' and './hookExample'.
26-
export const fooTypeChecked: (_1:{ readonly person: person }) => string = fooNotChecked;
26+
export const fooTypeChecked: (person:person) => string = fooNotChecked;
2727

2828
// Export 'foo' early to allow circular import from the '.bs.js' file.
29-
export const foo: unknown = fooTypeChecked as (_1:{ readonly person: person }) => string;
29+
export const foo: unknown = fooTypeChecked as (person:person) => string;
3030

3131
// tslint:disable-next-line:interface-over-type-literal
3232
export type person = { readonly name: string; readonly age: number };

jscomp/gentype_tests/typescript-react-example/src/LabeledFun.bs.js

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* TypeScript file generated from LabeledFun.res by genType. */
2+
/* eslint-disable import/first */
3+
4+
5+
// @ts-ignore: Implicit any on import
6+
import * as LabeledFunBS__Es6Import from './LabeledFun.bs';
7+
const LabeledFunBS: any = LabeledFunBS__Es6Import;
8+
9+
export const labelled: (a:number, b:number, c:number, _4:number, e:number, f:number) => number = LabeledFunBS.labelled;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@genType
2+
let labelled = (a, ~b=3, ~c, d, ~e, ~f) => a + b + c + d + e + f

jscomp/gentype_tests/typescript-react-example/src/TestPromise.gen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ export type toPayload = { readonly result: string };
1717

1818
export const convert: (_1:Promise<fromPayload>) => Promise<toPayload> = TestPromiseBS.convert;
1919

20-
export const barx: (_1:{ readonly x?: Promise<(undefined | string)> }, _2:void) => boolean = TestPromiseBS.barx;
20+
export const barx: (x:Promise<(undefined | string)>, _2:void) => boolean = TestPromiseBS.barx;

jscomp/gentype_tests/typescript-react-example/src/Uncurried.gen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,4 @@ export const sumU2: (n:number) => (_1:number) => void = UncurriedBS.sumU2;
4646

4747
export const sumCurried: (n:number, _2:number) => void = UncurriedBS.sumCurried;
4848

49-
export const sumLblCurried: (s:string, _2:{ readonly n: number; readonly m: number }) => void = UncurriedBS.sumLblCurried;
49+
export const sumLblCurried: (s:string, n:number, m:number) => void = UncurriedBS.sumLblCurried;

jscomp/gentype_tests/typescript-react-example/src/hookExample.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import * as React from "react";
22

3-
export const foo = (x: {
4-
person: { readonly name: string; readonly age: number };
5-
}) => x.person.name;
3+
export const foo = (person: { readonly name: string; readonly age: number }) => person.name;
64

75
type Props = {
86
readonly person: { readonly name: string; readonly age: number };

jscomp/gentype_tests/typescript-react-example/src/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ consoleLog(
6161
Uncurried.sumU(3, 4);
6262
Uncurried.sumU2(3)(4);
6363
Uncurried.sumCurried(3, 4);
64-
Uncurried.sumLblCurried("hello", { n: 3, m: 4 });
64+
Uncurried.sumLblCurried("hello", 3, 4);
6565

6666
ReactDOM.render(
6767
<div>

0 commit comments

Comments
 (0)