Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -62,6 +62,7 @@

#### :nail_care: Polish

- Omit unnecessary parentheses around coercions in call arguments, bindings, and collection elements while preserving expression grouping. https://github.com/rescript-lang/rescript/issues/6254
- Print external declarations in signatures and type errors with their processed attributes instead of the `"#rescript-external"` placeholder, and print inline constants using `@inline` syntax. https://github.com/rescript-lang/rescript/pull/8581
- Improve diagnostics for dynamic imports of local values and attempts to use `import` as a first-class value. https://github.com/rescript-lang/rescript/pull/8582
- Allow inferred labeled functions to be called with labels in any order by removing legacy curried-arrow commutation locks. https://github.com/rescript-lang/rescript/pull/8547
Expand Down
45 changes: 27 additions & 18 deletions compiler/syntax/src/res_parens.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Parsetree_viewer = Res_parsetree_viewer
type kind = Parenthesized | Braced of Location.t | Nothing

let expr expr =
let expr ?(allow_coercion = false) expr =
let opt_braces, _ = Parsetree_viewer.process_braces_attr expr in
match opt_braces with
| Some ({Location.loc = braces_loc}, _) -> Braced braces_loc
Expand All @@ -12,9 +12,17 @@ let expr expr =
Pexp_constraint ({pexp_desc = Pexp_pack _}, {ptyp_desc = Ptyp_package _});
} ->
Nothing
| {pexp_desc = Pexp_constraint _} -> Parenthesized
| {pexp_desc = Pexp_coerce _} when allow_coercion -> Nothing
| {pexp_desc = Pexp_constraint _ | Pexp_coerce _} -> Parenthesized
| _ -> Nothing)

(* A source annotation may precede :> directly, but nested coercions need
grouping. Preserve explicit braces through the normal expression rule. *)
let coerce_expr_operand expression =
match (expr expression, expression.Parsetree.pexp_desc) with
| Parenthesized, Pexp_constraint _ -> Nothing
Comment thread
cknitt marked this conversation as resolved.
Outdated
| kind, _ -> kind

let expr_record_row_rhs ~optional e =
let kind = expr e in
match kind with
Expand Down Expand Up @@ -50,9 +58,9 @@ let call_expr expr =
Nothing
| {
pexp_desc =
( Pexp_assert _ | Pexp_fun _ | Pexp_constraint _ | Pexp_setfield _
| Pexp_match _ | Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_for_of _
| Pexp_for_await_of _ | Pexp_ifthenelse _ );
( Pexp_assert _ | Pexp_fun _ | Pexp_constraint _ | Pexp_coerce _
| Pexp_setfield _ | Pexp_match _ | Pexp_try _ | Pexp_while _ | Pexp_for _
| Pexp_for_of _ | Pexp_for_await_of _ | Pexp_ifthenelse _ );
} ->
Parenthesized
| _ when Parsetree_viewer.expr_is_await expr -> Parenthesized
Expand All @@ -72,7 +80,7 @@ let structure_expr expr =
Pexp_constraint ({pexp_desc = Pexp_pack _}, {ptyp_desc = Ptyp_package _});
} ->
Nothing
| {pexp_desc = Pexp_constraint _} -> Parenthesized
| {pexp_desc = Pexp_constraint _ | Pexp_coerce _} -> Parenthesized
| _ -> Nothing)

let unary_expr_operand expr =
Expand Down Expand Up @@ -100,8 +108,8 @@ let unary_expr_operand expr =
Nothing
| {
pexp_desc =
( Pexp_assert _ | Pexp_fun _ | Pexp_constraint _ | Pexp_setfield _
| Pexp_extension _ (* readability? maybe remove *)
( Pexp_assert _ | Pexp_fun _ | Pexp_constraint _ | Pexp_coerce _
| Pexp_setfield _ | Pexp_extension _ (* readability? maybe remove *)
| Pexp_object_literal _ (* ({"a": 1})["a"] *)
| Pexp_object_set _ (* (o["x"] = v)["y"] *) | Pexp_match _ | Pexp_try _
| Pexp_while _ | Pexp_for _ | Pexp_for_of _ | Pexp_for_await_of _
Expand All @@ -125,7 +133,8 @@ let binary_expr_operand ~is_lhs expr =
| {pexp_desc = Pexp_fun _}
when Parsetree_viewer.is_underscore_apply_sugar expr ->
Nothing
| {pexp_desc = Pexp_constraint _ | Pexp_fun _} -> Parenthesized
| {pexp_desc = Pexp_constraint _ | Pexp_coerce _ | Pexp_fun _} ->
Parenthesized
| expr when Parsetree_viewer.is_binary_expression expr -> Parenthesized
| expr when Parsetree_viewer.is_ternary_expr expr -> Parenthesized
| {pexp_desc = Pexp_assert _} when is_lhs -> Parenthesized
Expand Down Expand Up @@ -182,7 +191,7 @@ let flatten_operand_rhs parent_operator rhs =
false
| Pexp_fun {params = {p_pat = {ppat_desc = Ppat_var {txt = "__x"}}} :: _} ->
false
| Pexp_fun _ | Pexp_setfield _ | Pexp_constraint _ -> true
| Pexp_fun _ | Pexp_setfield _ | Pexp_constraint _ | Pexp_coerce _ -> true
| _ when Parsetree_viewer.is_ternary_expr rhs -> true
| _ -> false

Expand Down Expand Up @@ -220,9 +229,9 @@ let assert_or_await_expr_rhs ?(in_await = false) expr =
Nothing
| {
pexp_desc =
( Pexp_assert _ | Pexp_fun _ | Pexp_constraint _ | Pexp_setfield _
| Pexp_match _ | Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_for_of _
| Pexp_for_await_of _ | Pexp_ifthenelse _ );
( Pexp_assert _ | Pexp_fun _ | Pexp_constraint _ | Pexp_coerce _
| Pexp_setfield _ | Pexp_match _ | Pexp_try _ | Pexp_while _ | Pexp_for _
| Pexp_for_of _ | Pexp_for_await_of _ | Pexp_ifthenelse _ );
} ->
Parenthesized
| _ when (not in_await) && Parsetree_viewer.expr_is_await expr ->
Expand Down Expand Up @@ -267,9 +276,9 @@ let field_expr expr =
pexp_desc =
( Pexp_assert _ | Pexp_extension _ (* %extension.x vs (%extension).x *)
| Pexp_object_literal _ (* ({"a": 1})["a"] *) | Pexp_fun _
| Pexp_constraint _ | Pexp_setfield _ | Pexp_match _ | Pexp_try _
| Pexp_while _ | Pexp_for _ | Pexp_for_of _ | Pexp_for_await_of _
| Pexp_ifthenelse _ );
| Pexp_constraint _ | Pexp_coerce _ | Pexp_setfield _ | Pexp_match _
| Pexp_try _ | Pexp_while _ | Pexp_for _ | Pexp_for_of _
| Pexp_for_await_of _ | Pexp_ifthenelse _ );
} ->
Parenthesized
| _ when Parsetree_viewer.expr_is_await expr -> Parenthesized
Expand All @@ -286,11 +295,11 @@ let ternary_operand expr =
Pexp_constraint ({pexp_desc = Pexp_pack _}, {ptyp_desc = Ptyp_package _});
} ->
Nothing
| {pexp_desc = Pexp_constraint _} -> Parenthesized
| {pexp_desc = Pexp_constraint _ | Pexp_coerce _} -> Parenthesized
| _ when Res_parsetree_viewer.is_fun_expr expr -> (
let _, _parameters, return_expr = Parsetree_viewer.fun_expr expr in
match return_expr.pexp_desc with
| Pexp_constraint _ -> Parenthesized
| Pexp_constraint _ | Pexp_coerce _ -> Parenthesized
| _ -> Nothing)
| _ -> Nothing)

Expand Down
7 changes: 6 additions & 1 deletion compiler/syntax/src/res_parens.mli
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
type kind = Parenthesized | Braced of Location.t | Nothing

val expr : Parsetree.expression -> kind
(* Set [allow_coercion] to [true] only in grammar positions accepting a trailing
coercion without parentheses, such as call arguments and binding right-hand
sides. Arrow bodies require parentheses. *)
val expr : ?allow_coercion:bool -> Parsetree.expression -> kind
val structure_expr : Parsetree.expression -> kind

val unary_expr_operand : Parsetree.expression -> kind
Expand Down Expand Up @@ -37,3 +40,5 @@ val arrow_return_typ_expr : Parsetree.core_type -> bool
val pattern_record_row_rhs : Parsetree.pattern -> bool

val expr_record_row_rhs : optional:bool -> Parsetree.expression -> kind

val coerce_expr_operand : Parsetree.expression -> kind
54 changes: 32 additions & 22 deletions compiler/syntax/src/res_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,7 @@ and print_spread_dict_expr ~state parts (expr : Parsetree.expression) cmt_tbl =
in
let spread_doc =
let doc = print_expression ~state spread_expr cmt_tbl in
match Parens.expr spread_expr with
match Parens.expr ~allow_coercion:true spread_expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc spread_expr braces
| Nothing -> doc
Expand Down Expand Up @@ -2473,7 +2473,7 @@ and print_value_binding ~state ~rec_flag (vb : Parsetree.value_binding) cmt_tbl
let opt_braces, expr = Parsetree_viewer.process_braces_attr vb.pvb_expr in
let printed_expr =
let doc = print_expression_with_comments ~state vb.pvb_expr cmt_tbl in
match Parens.expr vb.pvb_expr with
match Parens.expr ~allow_coercion:true vb.pvb_expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc
Expand Down Expand Up @@ -3244,7 +3244,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
Doc.line;
Doc.dotdotdot;
(let doc = print_expression_with_comments ~state expr cmt_tbl in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc);
Expand All @@ -3266,7 +3266,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
let doc =
print_expression_with_comments ~state expr cmt_tbl
in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc)
Expand All @@ -3291,7 +3291,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
[
Doc.lparen;
(let doc = print_expression_with_comments ~state arg cmt_tbl in
match Parens.expr arg with
match Parens.expr ~allow_coercion:true arg with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc arg braces
| Nothing -> doc);
Expand All @@ -3312,7 +3312,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
let doc =
print_expression_with_comments ~state expr cmt_tbl
in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc)
Expand All @@ -3325,7 +3325,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
| Some arg ->
let arg_doc =
let doc = print_expression_with_comments ~state arg cmt_tbl in
match Parens.expr arg with
match Parens.expr ~allow_coercion:true arg with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc arg braces
| Nothing -> doc
Expand Down Expand Up @@ -3363,7 +3363,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
let doc =
print_expression_with_comments ~state expr cmt_tbl
in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc)
Expand Down Expand Up @@ -3392,7 +3392,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
let doc =
print_expression_with_comments ~state expr cmt_tbl
in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc)
Expand All @@ -3418,7 +3418,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
[
Doc.lparen;
(let doc = print_expression_with_comments ~state arg cmt_tbl in
match Parens.expr arg with
match Parens.expr ~allow_coercion:true arg with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc arg braces
| Nothing -> doc);
Expand All @@ -3439,7 +3439,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
let doc =
print_expression_with_comments ~state expr cmt_tbl
in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc)
Expand All @@ -3452,7 +3452,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
| Some arg ->
let arg_doc =
let doc = print_expression_with_comments ~state arg cmt_tbl in
match Parens.expr arg with
match Parens.expr ~allow_coercion:true arg with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc arg braces
| Nothing -> doc
Expand Down Expand Up @@ -3491,7 +3491,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
Doc.concat
[
Doc.dotdotdot;
(match Parens.expr expr with
(match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc);
Expand Down Expand Up @@ -3843,7 +3843,17 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl =
| Pexp_coerce (expr, (), typ) ->
let doc_expr = print_expression_with_comments ~state expr cmt_tbl in
let doc_typ = print_typ_expr ~state typ cmt_tbl in
Doc.concat [Doc.lparen; doc_expr; Doc.text " :> "; doc_typ; Doc.rparen]
let doc_expr =
match Parens.coerce_expr_operand expr with
| Parens.Parenthesized -> add_parens doc_expr
| Braced braces -> print_braces doc_expr expr braces
| Nothing -> doc_expr
in
let doc = Doc.concat [doc_expr; Doc.text " :> "; doc_typ] in
(* Keep attributes on the coercion rather than its operand. *)
if Parsetree_viewer.has_printable_attributes e.pexp_attributes then
add_parens doc
else doc
| Pexp_object_get (parent_expr, label) ->
print_object_get_doc ~state parent_expr label cmt_tbl
| Pexp_object_set (obj, member, rhs) ->
Expand Down Expand Up @@ -4344,7 +4354,7 @@ and print_array_spread_apply ~state sub_lists cmt_tbl =
(* Print expression without leading comments (they're already extracted) *)
let expr_doc =
let doc = print_expression ~state expr cmt_tbl in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc
Expand Down Expand Up @@ -4376,7 +4386,7 @@ and print_array_spread_apply ~state sub_lists cmt_tbl =
(List.map
(fun expr ->
let doc = print_expression_with_comments ~state expr cmt_tbl in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc)
Expand Down Expand Up @@ -4411,7 +4421,7 @@ and print_list_spread_apply ~state sub_lists cmt_tbl =
comma_before_spread;
Doc.dotdotdot;
(let doc = print_expression_with_comments ~state expr cmt_tbl in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc);
Expand All @@ -4432,7 +4442,7 @@ and print_list_spread_apply ~state sub_lists cmt_tbl =
(List.map
(fun expr ->
let doc = print_expression_with_comments ~state expr cmt_tbl in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc)
Expand Down Expand Up @@ -4532,7 +4542,7 @@ and print_pexp_apply ~state expr cmt_tbl =
let member =
let member_doc =
let doc = print_expression_with_comments ~state member_expr cmt_tbl in
match Parens.expr member_expr with
match Parens.expr ~allow_coercion:true member_expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc member_expr braces
| Nothing -> doc
Expand Down Expand Up @@ -4579,7 +4589,7 @@ and print_pexp_apply ~state expr cmt_tbl =
let member =
let member_doc =
let doc = print_expression_with_comments ~state member_expr cmt_tbl in
match Parens.expr member_expr with
match Parens.expr ~allow_coercion:true member_expr with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc member_expr braces
| Nothing -> doc
Expand Down Expand Up @@ -5247,7 +5257,7 @@ and print_arguments ~state ~partial
| [(Nolabel, arg)] when Parsetree_viewer.is_huggable_expression arg ->
let arg_doc =
let doc = print_expression_with_comments ~state arg cmt_tbl in
match Parens.expr arg with
match Parens.expr ~allow_coercion:true arg with
| Parens.Parenthesized -> add_parens doc
| Braced braces -> print_braces doc arg braces
| Nothing -> doc
Expand Down Expand Up @@ -5350,7 +5360,7 @@ and print_argument ~state (arg_lbl, arg) cmt_tbl =
in
let printed_expr =
let doc = print_expression_with_comments ~state expr cmt_tbl in
match Parens.expr expr with
match Parens.expr ~allow_coercion:true expr with
| Parenthesized -> add_parens doc
| Braced braces -> print_braces doc expr braces
| Nothing -> doc
Expand Down
Loading
Loading