Skip to content

Commit 27cffed

Browse files
committed
Extend untyped and types ast with async attribute.
1 parent 0745025 commit 27cffed

26 files changed

+124
-84
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
- AST cleanup: Prepare for ast async cleanup: Refactor code for "@res.async" payload handling and clean up handling of type and term parameters, so that now each `=>` in a function definition corresponds to a function. https://github.com/rescript-lang/rescript/pull/7223
2323
- AST: always put type parameters first in function definitions. https://github.com/rescript-lang/rescript/pull/7233
24+
- AST cleanup: Remove `@res.async` attribute from the internal representation, and add a flag to untyped and typed ASTs instead. https://github.com/rescript-lang/rescript/pull/7234
2425

2526
# 12.0.0-alpha.7
2627

compiler/frontend/ast_compatible.ml

+9-2
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,20 @@ let app3 ?(loc = default_loc) ?(attrs = []) fn arg1 arg2 arg3 : expression =
6464
Pexp_apply (fn, [(Nolabel, arg1); (Nolabel, arg2); (Nolabel, arg3)]);
6565
}
6666

67-
let fun_ ?(loc = default_loc) ?(attrs = []) ~arity pat exp =
67+
let fun_ ?(loc = default_loc) ?(attrs = []) ?(async = false) ~arity pat exp =
6868
{
6969
pexp_loc = loc;
7070
pexp_attributes = attrs;
7171
pexp_desc =
7272
Pexp_fun
73-
{arg_label = Nolabel; default = None; lhs = pat; rhs = exp; arity};
73+
{
74+
arg_label = Nolabel;
75+
default = None;
76+
lhs = pat;
77+
rhs = exp;
78+
arity;
79+
async;
80+
};
7481
}
7582

7683
let const_exp_string ?(loc = default_loc) ?(attrs = []) ?delimiter (s : string)

compiler/frontend/ast_compatible.mli

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ val apply_labels :
7474
val fun_ :
7575
?loc:Location.t ->
7676
?attrs:attrs ->
77+
?async:bool ->
7778
arity:int option ->
7879
pattern ->
7980
expression ->

compiler/frontend/ast_uncurry_gen.ml

+5-5
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ let to_method_callback loc (self : Bs_ast_mapper.mapper) label
3636
match Ast_attributes.process_attributes_rev body.pexp_attributes with
3737
| Nothing, attrs -> (
3838
match body.pexp_desc with
39-
| Pexp_fun {arg_label; lhs = arg; rhs = body} ->
39+
| Pexp_fun {arg_label; lhs = arg; rhs = body; async} ->
4040
Bs_syntaxerr.optional_err loc arg_label;
41-
aux ((arg_label, self.pat self arg, attrs) :: acc) body
41+
aux ((arg_label, self.pat self arg, attrs, async) :: acc) body
4242
| _ -> (self.expr self body, acc))
4343
| _, _ -> (self.expr self body, acc)
4444
in
45-
let result, rev_extra_args = aux [(label, self_pat, [])] body in
45+
let result, rev_extra_args = aux [(label, self_pat, [], false)] body in
4646
let body =
47-
Ext_list.fold_left rev_extra_args result (fun e (label, p, attrs) ->
48-
Ast_helper.Exp.fun_ ~loc ~attrs ~arity:None label None p e)
47+
Ext_list.fold_left rev_extra_args result (fun e (label, p, attrs, async) ->
48+
Ast_helper.Exp.fun_ ~loc ~attrs ~arity:None ~async label None p e)
4949
in
5050
let arity = List.length rev_extra_args in
5151
let arity_s = string_of_int arity in

compiler/frontend/bs_ast_mapper.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,9 @@ module E = struct
315315
sub vbs)
316316
(sub.expr sub e)
317317
(* #end *)
318-
| Pexp_fun {arg_label = lab; default = def; lhs = p; rhs = e; arity} ->
319-
fun_ ~loc ~attrs ~arity lab
318+
| Pexp_fun {arg_label = lab; default = def; lhs = p; rhs = e; arity; async}
319+
->
320+
fun_ ~loc ~attrs ~arity ~async lab
320321
(map_opt (sub.expr sub) def)
321322
(sub.pat sub p) (sub.expr sub e)
322323
| Pexp_apply (e, l) ->

compiler/frontend/bs_builtin_ppx.ml

+1-2
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
113113
| Pexp_newtype (s, body) ->
114114
let res = self.expr self body in
115115
{e with pexp_desc = Pexp_newtype (s, res)}
116-
| Pexp_fun {arg_label = label; lhs = pat; rhs = body} -> (
117-
let async = Ast_async.has_async_payload e.pexp_attributes in
116+
| Pexp_fun {arg_label = label; lhs = pat; rhs = body; async} -> (
118117
match Ast_attributes.process_attributes_rev e.pexp_attributes with
119118
| Nothing, _ ->
120119
(* Handle @async x => y => ... is in async context *)

compiler/ml/ast_async.ml

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,16 @@
1-
let has_async_payload attrs =
2-
Ext_list.exists attrs (fun ({Location.txt}, _) -> txt = "res.async")
3-
41
let rec dig_async_payload_from_function (expr : Parsetree.expression) =
52
match expr.pexp_desc with
6-
| Pexp_fun _ -> has_async_payload expr.pexp_attributes
3+
| Pexp_fun {async} -> async
74
| Pexp_newtype (_, body) -> dig_async_payload_from_function body
85
| _ -> false
96

107
let add_async_attribute ~async (body : Parsetree.expression) =
11-
let add (exp : Parsetree.expression) =
12-
if has_async_payload exp.pexp_attributes then exp
13-
else
14-
{
15-
exp with
16-
pexp_attributes =
17-
({txt = "res.async"; loc = Location.none}, PStr [])
18-
:: exp.pexp_attributes;
19-
}
20-
in
218
if async then
229
let rec add_to_fun (exp : Parsetree.expression) =
2310
match exp.pexp_desc with
2411
| Pexp_newtype (txt, e) ->
2512
{exp with pexp_desc = Pexp_newtype (txt, add_to_fun e)}
26-
| Pexp_fun _ -> add exp
13+
| Pexp_fun f -> {exp with pexp_desc = Pexp_fun {f with async}}
2714
| _ -> exp
2815
in
2916
add_to_fun body

compiler/ml/ast_helper.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ module Exp = struct
151151
let ident ?loc ?attrs a = mk ?loc ?attrs (Pexp_ident a)
152152
let constant ?loc ?attrs a = mk ?loc ?attrs (Pexp_constant a)
153153
let let_ ?loc ?attrs a b c = mk ?loc ?attrs (Pexp_let (a, b, c))
154-
let fun_ ?loc ?attrs ~arity a b c d =
154+
let fun_ ?loc ?attrs ?(async = false) ~arity a b c d =
155155
mk ?loc ?attrs
156-
(Pexp_fun {arg_label = a; default = b; lhs = c; rhs = d; arity})
156+
(Pexp_fun {arg_label = a; default = b; lhs = c; rhs = d; arity; async})
157157
let apply ?loc ?attrs a b = mk ?loc ?attrs (Pexp_apply (a, b))
158158
let match_ ?loc ?attrs a b = mk ?loc ?attrs (Pexp_match (a, b))
159159
let try_ ?loc ?attrs a b = mk ?loc ?attrs (Pexp_try (a, b))

compiler/ml/ast_helper.mli

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ module Exp : sig
138138
val fun_ :
139139
?loc:loc ->
140140
?attrs:attrs ->
141+
?async:bool ->
141142
arity:int option ->
142143
arg_label ->
143144
expression option ->

compiler/ml/ast_mapper.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,9 @@ module E = struct
278278
| Pexp_constant x -> constant ~loc ~attrs x
279279
| Pexp_let (r, vbs, e) ->
280280
let_ ~loc ~attrs r (List.map (sub.value_binding sub) vbs) (sub.expr sub e)
281-
| Pexp_fun {arg_label = lab; default = def; lhs = p; rhs = e; arity} ->
282-
fun_ ~loc ~attrs ~arity lab
281+
| Pexp_fun {arg_label = lab; default = def; lhs = p; rhs = e; arity; async}
282+
->
283+
fun_ ~loc ~attrs ~arity ~async lab
283284
(map_opt (sub.expr sub) def)
284285
(sub.pat sub p) (sub.expr sub e)
285286
| Pexp_apply (e, l) ->

compiler/ml/ast_mapper_from0.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ module E = struct
304304
| Pexp_let (r, vbs, e) ->
305305
let_ ~loc ~attrs r (List.map (sub.value_binding sub) vbs) (sub.expr sub e)
306306
| Pexp_fun (lab, def, p, e) ->
307-
fun_ ~loc ~attrs ~arity:None lab
307+
let async = Ext_list.exists attrs (fun ({txt}, _) -> txt = "res.async") in
308+
fun_ ~loc ~attrs ~async ~arity:None lab
308309
(map_opt (sub.expr sub) def)
309310
(sub.pat sub p) (sub.expr sub e)
310311
| Pexp_function _ -> assert false

compiler/ml/ast_mapper_to0.ml

+7-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,13 @@ module E = struct
295295
| Pexp_constant x -> constant ~loc ~attrs (map_constant x)
296296
| Pexp_let (r, vbs, e) ->
297297
let_ ~loc ~attrs r (List.map (sub.value_binding sub) vbs) (sub.expr sub e)
298-
| Pexp_fun {arg_label = lab; default = def; lhs = p; rhs = e; arity} -> (
298+
| Pexp_fun {arg_label = lab; default = def; lhs = p; rhs = e; arity; async}
299+
-> (
300+
let attrs =
301+
if async then
302+
({txt = "res.async"; loc = Location.none}, Pt.PStr []) :: attrs
303+
else attrs
304+
in
299305
let e =
300306
fun_ ~loc ~attrs lab
301307
(map_opt (sub.expr sub) def)

compiler/ml/parsetree.ml

+1
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ and expression_desc =
230230
lhs: pattern;
231231
rhs: expression;
232232
arity: arity;
233+
async: bool;
233234
}
234235
(* fun P -> E1 (Simple, None)
235236
fun ~l:P -> E1 (Labelled l, None)

compiler/ml/pprintast.ml

+4-3
Original file line numberDiff line numberDiff line change
@@ -605,14 +605,15 @@ and expression ctxt f x =
605605
| (Pexp_let _ | Pexp_letmodule _ | Pexp_open _ | Pexp_letexception _)
606606
when ctxt.semi ->
607607
paren true (expression reset_ctxt) f x
608-
| Pexp_fun {arg_label = l; default = e0; lhs = p; rhs = e; arity} ->
608+
| Pexp_fun {arg_label = l; default = e0; lhs = p; rhs = e; arity; async} ->
609609
let arity_str =
610610
match arity with
611611
| None -> ""
612612
| Some arity -> "[arity:" ^ string_of_int arity ^ "]"
613613
in
614-
pp f "@[<2>fun@;%s%a->@;%a@]" arity_str (label_exp ctxt) (l, e0, p)
615-
(expression ctxt) e
614+
let async_str = if async then "async " else "" in
615+
pp f "@[<2>%sfun@;%s%a->@;%a@]" async_str arity_str (label_exp ctxt)
616+
(l, e0, p) (expression ctxt) e
616617
| Pexp_match (e, l) ->
617618
pp f "@[<hv0>@[<hv0>@[<2>match %a@]@ with@]%a@]" (expression reset_ctxt) e
618619
(case_list ctxt) l

compiler/ml/printast.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,9 @@ and expression i ppf x =
238238
line i ppf "Pexp_let %a\n" fmt_rec_flag rf;
239239
list i value_binding ppf l;
240240
expression i ppf e
241-
| Pexp_fun {arg_label = l; default = eo; lhs = p; rhs = e; arity} ->
241+
| Pexp_fun {arg_label = l; default = eo; lhs = p; rhs = e; arity; async} ->
242242
line i ppf "Pexp_fun\n";
243+
let () = if async then line i ppf "async\n" in
243244
let () =
244245
match arity with
245246
| None -> ()

compiler/ml/printtyped.ml

+3-1
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,10 @@ and expression i ppf x =
285285
line i ppf "Texp_let %a\n" fmt_rec_flag rf;
286286
list i value_binding ppf l;
287287
expression i ppf e
288-
| Texp_function {arg_label = p; arity; param; case = case_; partial = _} ->
288+
| Texp_function
289+
{arg_label = p; arity; async; param; case = case_; partial = _} ->
289290
line i ppf "Texp_function\n";
291+
if async then line i ppf "async\n";
290292
(match arity with
291293
| Some arity -> line i ppf "arity: %d\n" arity
292294
| None -> ());

compiler/ml/tast_mapper.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,9 @@ let expr sub x =
199199
| Texp_let (rec_flag, list, exp) ->
200200
let rec_flag, list = sub.value_bindings sub (rec_flag, list) in
201201
Texp_let (rec_flag, list, sub.expr sub exp)
202-
| Texp_function {arg_label; arity; param; case; partial} ->
203-
Texp_function {arg_label; arity; param; case = sub.case sub case; partial}
202+
| Texp_function {arg_label; arity; param; case; partial; async} ->
203+
Texp_function
204+
{arg_label; arity; param; case = sub.case sub case; partial; async}
204205
| Texp_apply (exp, list) ->
205206
Texp_apply
206207
(sub.expr sub exp, List.map (tuple2 id (opt (sub.expr sub))) list)

compiler/ml/translcore.ml

+7-6
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,8 @@ let rec push_defaults loc bindings case partial =
555555
c_lhs = pat;
556556
c_guard = None;
557557
c_rhs =
558-
{exp_desc = Texp_function {arg_label; arity; param; case; partial}} as exp;
558+
{exp_desc = Texp_function {arg_label; arity; param; case; partial; async}}
559+
as exp;
559560
} ->
560561
let case = push_defaults exp.exp_loc bindings case partial in
561562

@@ -565,7 +566,8 @@ let rec push_defaults loc bindings case partial =
565566
c_rhs =
566567
{
567568
exp with
568-
exp_desc = Texp_function {arg_label; arity; param; case; partial};
569+
exp_desc =
570+
Texp_function {arg_label; arity; param; case; partial; async};
569571
};
570572
}
571573
| {
@@ -671,8 +673,7 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
671673
| Texp_constant cst -> Lconst (Const_base cst)
672674
| Texp_let (rec_flag, pat_expr_list, body) ->
673675
transl_let rec_flag pat_expr_list (transl_exp body)
674-
| Texp_function {arg_label = _; arity; param; case; partial} -> (
675-
let async = Ast_async.has_async_payload e.exp_attributes in
676+
| Texp_function {arg_label = _; arity; param; case; partial; async} -> (
676677
let directive =
677678
match extract_directive_for_fn e with
678679
| None -> None
@@ -1050,11 +1051,11 @@ and transl_function loc partial param case =
10501051
param = param';
10511052
case;
10521053
partial = partial';
1054+
async;
10531055
};
10541056
} as exp;
10551057
}
1056-
when Parmatch.inactive ~partial pat
1057-
&& not (Ast_async.has_async_payload exp.exp_attributes) ->
1058+
when Parmatch.inactive ~partial pat && not async ->
10581059
let params, body, return_unit =
10591060
transl_function exp.exp_loc partial' param' case
10601061
in

compiler/ml/typecore.ml

+18-6
Original file line numberDiff line numberDiff line change
@@ -2364,7 +2364,14 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
23642364
exp_env = env;
23652365
}
23662366
| Pexp_fun
2367-
{arg_label = l; default = Some default; lhs = spat; rhs = sbody; arity} ->
2367+
{
2368+
arg_label = l;
2369+
default = Some default;
2370+
lhs = spat;
2371+
rhs = sbody;
2372+
arity;
2373+
async;
2374+
} ->
23682375
assert (is_optional l);
23692376
(* default allowed only with optional argument *)
23702377
let open Ast_helper in
@@ -2402,10 +2409,13 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
24022409
[Vb.mk spat smatch]
24032410
sbody
24042411
in
2405-
type_function ?in_function ~arity loc sexp.pexp_attributes env ty_expected l
2412+
type_function ?in_function ~arity ~async loc sexp.pexp_attributes env
2413+
ty_expected l
24062414
[Exp.case pat body]
2407-
| Pexp_fun {arg_label = l; default = None; lhs = spat; rhs = sbody; arity} ->
2408-
type_function ?in_function ~arity loc sexp.pexp_attributes env ty_expected l
2415+
| Pexp_fun
2416+
{arg_label = l; default = None; lhs = spat; rhs = sbody; arity; async} ->
2417+
type_function ?in_function ~arity ~async loc sexp.pexp_attributes env
2418+
ty_expected l
24092419
[Ast_helper.Exp.case spat sbody]
24102420
| Pexp_apply (sfunct, sargs) ->
24112421
assert (sargs <> []);
@@ -3246,7 +3256,8 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp
32463256
| Pexp_extension ext ->
32473257
raise (Error_forward (Builtin_attributes.error_of_extension ext))
32483258
3249-
and type_function ?in_function ~arity loc attrs env ty_expected_ l caselist =
3259+
and type_function ?in_function ~arity ~async loc attrs env ty_expected_ l
3260+
caselist =
32503261
let state = Warnings.backup () in
32513262
(* Disable Unerasable_optional_argument for uncurried functions *)
32523263
let unerasable_optional_argument =
@@ -3304,7 +3315,8 @@ and type_function ?in_function ~arity loc attrs env ty_expected_ l caselist =
33043315
Warnings.restore state;
33053316
re
33063317
{
3307-
exp_desc = Texp_function {arg_label = l; arity; param; case; partial};
3318+
exp_desc =
3319+
Texp_function {arg_label = l; arity; param; case; partial; async};
33083320
exp_loc = loc;
33093321
exp_extra = [];
33103322
exp_type;

compiler/ml/typedtree.ml

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ and expression_desc =
8282
param: Ident.t;
8383
case: case;
8484
partial: partial;
85+
async: bool;
8586
}
8687
| Texp_apply of expression * (arg_label * expression option) list
8788
| Texp_match of expression * case list * case list * partial

compiler/ml/typedtree.mli

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ and expression_desc =
136136
param: Ident.t;
137137
case: case;
138138
partial: partial;
139+
async: bool;
139140
}
140141
(** [Pexp_fun] and [Pexp_function] both translate to [Texp_function].
141142
See {!Parsetree} for more details.

compiler/syntax/src/res_parsetree_viewer.ml

+4-4
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ let filter_parsing_attrs attrs =
214214
| ( {
215215
Location.txt =
216216
( "res.braces" | "ns.braces" | "res.iflet" | "res.namedArgLoc"
217-
| "res.ternary" | "res.async" | "res.await" | "res.template"
217+
| "res.ternary" | "res.await" | "res.template"
218218
| "res.taggedTemplate" | "res.patVariantSpread"
219219
| "res.dictPattern" );
220220
},
@@ -365,7 +365,7 @@ let has_attributes attrs =
365365
| ( {
366366
Location.txt =
367367
( "res.braces" | "ns.braces" | "res.iflet" | "res.ternary"
368-
| "res.async" | "res.await" | "res.template" );
368+
| "res.await" | "res.template" );
369369
},
370370
_ ) ->
371371
false
@@ -548,8 +548,8 @@ let is_printable_attribute attr =
548548
match attr with
549549
| ( {
550550
Location.txt =
551-
( "res.iflet" | "res.braces" | "ns.braces" | "JSX" | "res.async"
552-
| "res.await" | "res.template" | "res.ternary" );
551+
( "res.iflet" | "res.braces" | "ns.braces" | "JSX" | "res.await"
552+
| "res.template" | "res.ternary" );
553553
},
554554
_ ) ->
555555
false

tests/syntax_tests/data/parsing/grammar/expressions/expected/UncurriedByDefault.res.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ type nonrec unested = (string -> unit (a:1)) -> unit (a:1)
3737
let (uannpoly : 'a -> string (a:1)) = xx
3838
let (uannint : int -> string (a:1)) = xx
3939
let _ = ((fun [arity:1]x -> 34)[@att ])
40-
let _ = ((fun [arity:1]x -> 34)[@res.async ][@att ])
40+
let _ = ((async fun [arity:1]x -> 34)[@att ])
4141
let _ = preserveAttr ((fun [arity:1]x -> 34)[@att ])
42-
let _ = preserveAttr ((fun [arity:1]x -> 34)[@res.async ][@att ])
42+
let _ = preserveAttr ((async fun [arity:1]x -> 34)[@att ])
4343
let t0 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l
4444
let t1 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l
4545
let t2 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l
@@ -95,9 +95,9 @@ let pipe1 = 3 |.u f
9595
let (uannpoly : 'a -> string (a:1)) = xx
9696
let (uannint : int -> string (a:1)) = xx
9797
let _ = ((fun [arity:1]x -> 34)[@att ])
98-
let _ = ((fun [arity:1]x -> 34)[@res.async ][@att ])
98+
let _ = ((async fun [arity:1]x -> 34)[@att ])
9999
let _ = preserveAttr ((fun [arity:1]x -> 34)[@att ])
100-
let _ = preserveAttr ((fun [arity:1]x -> 34)[@res.async ][@att ])
100+
let _ = preserveAttr ((async fun [arity:1]x -> 34)[@att ])
101101
let t0 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l
102102
let t1 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l
103103
let t2 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l

0 commit comments

Comments
 (0)