diff --git a/changes/async-guard-lookahead.fix.md b/changes/async-guard-lookahead.fix.md new file mode 100644 index 0000000000..ae06bb70d6 --- /dev/null +++ b/changes/async-guard-lookahead.fix.md @@ -0,0 +1 @@ +- Parse a switch guard that calls a function named `async`. diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 222cffc834..8ffd5d1cad 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -2321,11 +2321,14 @@ and parse_operand_expr ~context p = (* we need to be careful when we're in a ternary true branch: `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 + 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 `=>`. *) - when is_es6_arrow_expression - ~in_ternary:(context = TernaryTrueBranchExpr) - p -> + when context != WhenExpr + && is_es6_arrow_expression + ~in_ternary:(context = TernaryTrueBranchExpr) + p -> let arrow_attrs = !attrs in let () = attrs := [] in parse_async_arrow_expression ~arrow_attrs p diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/async.res b/tests/syntax_tests/data/parsing/grammar/expressions/async.res index 8828e7d05e..da7205342e 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/async.res +++ b/tests/syntax_tests/data/parsing/grammar/expressions/async.res @@ -42,3 +42,10 @@ let attr2 = @a async (type a) => (type b c, x) => 3 let attr3 = @a (type a) => async (type b c, x) => 3 let attr4 = @a (type a) => @b async (type b c, x) => 3 let attr5 : int = @a @b async (type a, type b c) => (x:a) => x + +// A guard calling a function named async is a call, not an async arrow +let guarded = v => + switch v { + | Some(x) if async(x) => async () => x + | _ => async () => 0 + } diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt index c34d7be652..65a9cfdbba 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt @@ -36,4 +36,8 @@ let attr4 = let (attr5 : int) = ((async fun (type a) (type b) (type c) [arity:1]() -> fun [arity:1](x : a) -> x) - [@a ][@b ]) \ No newline at end of file + [@a ][@b ]) +let guarded [arity:1]v = + match v with + | Some x when async x -> (async fun [arity:1]() -> x) + | _ -> (async fun [arity:1]() -> 0) \ No newline at end of file