Skip to content
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
14 changes: 8 additions & 6 deletions compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,10 @@ type record_pattern_item =
| PatField of Parsetree.pattern Parsetree.record_element
| PatRest of Parsetree.record_pat_rest

type context = OrdinaryExpr | TernaryTrueBranchExpr | WhenExpr
(* [WhenExpr] is an expression followed by a block, such as a condition or a
switch scrutinee. [GuardExpr] is a switch guard, which the case's [=>]
follows. *)
type context = OrdinaryExpr | TernaryTrueBranchExpr | WhenExpr | GuardExpr

(* Extracts type and term parameters from a list of function definition
parameters, keeping the type parameter groups in source order *)
Expand Down Expand Up @@ -2322,10 +2325,9 @@ and parse_operand_expr ~context p =
`condition ? ternary-true-branch : false-branch`
Arrow expressions could be of the form: `async (): int => stuff()`
But if we're in a ternary, the `:` of the ternary takes precedence.
Like other arrows, none starts in a guard or a condition, where
`async(x) =>` is a call followed by the case's `=>`.
In a guard, `async(x) =>` is a call followed by the case's `=>`.
*)
when context != WhenExpr
when context != GuardExpr
&& is_es6_arrow_expression
~in_ternary:(context = TernaryTrueBranchExpr)
p ->
Expand All @@ -2340,7 +2342,7 @@ and parse_operand_expr ~context p =
| Switch -> parse_switch_expression p
| _ ->
if
context != WhenExpr
context != WhenExpr && context != GuardExpr
&& is_es6_arrow_expression
~in_ternary:(context = TernaryTrueBranchExpr)
p
Expand Down Expand Up @@ -3825,7 +3827,7 @@ and parse_pattern_guard p =
match Parser.peek p with
| When | If ->
Parser.next p;
Some (parse_expr ~context:WhenExpr p)
Some (parse_expr ~context:GuardExpr p)
| _ -> None

and parse_pattern_match_case p =
Expand Down
12 changes: 12 additions & 0 deletions tests/syntax_tests/data/parsing/grammar/expressions/async.res
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,15 @@ let guarded = v =>
| Some(x) if async(x) => async () => x
| _ => async () => 0
}

// Outside guards, async arrows parse wherever expressions do
let scrutinee = switch async () => 1 {
| _ => 0
}

// A parenthesized guard is not an arrow either
let parenthesizedGuard = v =>
switch v {
| Some(x) if (x) => 1
| _ => 0
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ let (attr5 : int) =
let guarded [arity:1]v =
match v with
| Some x when async x -> (async fun [arity:1]() -> x)
| _ -> (async fun [arity:1]() -> 0)
| _ -> (async fun [arity:1]() -> 0)
let scrutinee = match async fun [arity:1]() -> 1 with | _ -> 0
let parenthesizedGuard [arity:1]v =
match v with | Some x when x -> 1 | _ -> 0
Loading