Skip to content

Commit d2f5ffa

Browse files
authored
Fix parameter type / return type ambiguity error for unit case (#7930)
* Fix parameter type / return type ambiguity error for unit case * format * CHANGELOG
1 parent 57c696b commit d2f5ffa

File tree

6 files changed

+53
-37
lines changed

6 files changed

+53
-37
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#### :bug: Bug fix
2424

2525
- Prevent lockfile creation when project folder is missing. https://github.com/rescript-lang/rescript/pull/7927
26+
- Fix parameter type / return type ambiguity error for unit case. https://github.com/rescript-lang/rescript/pull/7930
2627

2728
#### :memo: Documentation
2829

compiler/syntax/src/res_core.ml

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2554,54 +2554,62 @@ and over_parse_constrained_or_coerced_or_arrow_expression p expr =
25542554
| EqualGreater ->
25552555
Parser.next p;
25562556
let body = parse_expr p in
2557-
let pat =
2557+
let pat, expr_is_unit =
25582558
match expr.pexp_desc with
25592559
| Pexp_ident longident ->
2560-
Ast_helper.Pat.var ~loc:expr.pexp_loc
2561-
(Location.mkloc
2562-
(Longident.flatten longident.txt |> String.concat ".")
2563-
longident.loc)
2560+
( Ast_helper.Pat.var ~loc:expr.pexp_loc
2561+
(Location.mkloc
2562+
(Longident.flatten longident.txt |> String.concat ".")
2563+
longident.loc),
2564+
false )
2565+
| Pexp_construct (({txt = Longident.Lident "()"} as lid), None) ->
2566+
(Ast_helper.Pat.construct ~loc:expr.pexp_loc lid None, true)
25642567
(* TODO: can we convert more expressions to patterns?*)
25652568
| _ ->
2566-
Ast_helper.Pat.var ~loc:expr.pexp_loc
2567-
(Location.mkloc "pattern" expr.pexp_loc)
2569+
( Ast_helper.Pat.var ~loc:expr.pexp_loc
2570+
(Location.mkloc "pattern" expr.pexp_loc),
2571+
false )
25682572
in
25692573
let arrow1 =
25702574
Ast_helper.Exp.fun_
25712575
~loc:(mk_loc expr.pexp_loc.loc_start body.pexp_loc.loc_end)
25722576
~arity:None Asttypes.Nolabel None pat
25732577
(Ast_helper.Exp.constraint_ body typ)
25742578
in
2575-
let arrow2 =
2576-
Ast_helper.Exp.fun_
2577-
~loc:(mk_loc expr.pexp_loc.loc_start body.pexp_loc.loc_end)
2578-
~arity:None Asttypes.Nolabel None
2579-
(Ast_helper.Pat.constraint_ pat typ)
2580-
body
2581-
in
2582-
let msg =
2583-
Doc.breakable_group ~force_break:true
2584-
(Doc.concat
2585-
[
2586-
Doc.text
2587-
"Did you mean to annotate the parameter type or the return \
2588-
type?";
2589-
Doc.indent
2590-
(Doc.concat
2591-
[
2592-
Doc.line;
2593-
Doc.text "1) ";
2594-
ResPrinter.print_expression arrow1 CommentTable.empty;
2595-
Doc.line;
2596-
Doc.text "2) ";
2597-
ResPrinter.print_expression arrow2 CommentTable.empty;
2598-
]);
2599-
])
2600-
|> Doc.to_string ~width:80
2601-
in
2602-
Parser.err ~start_pos:expr.pexp_loc.loc_start
2603-
~end_pos:body.pexp_loc.loc_end p (Diagnostics.message msg);
2604-
arrow1
2579+
(* When the "expr" was `()`, the colon must apply to the return type, so
2580+
skip the ambiguity diagnostic and keep the parameter as unit. *)
2581+
if expr_is_unit then arrow1
2582+
else
2583+
let arrow2 =
2584+
Ast_helper.Exp.fun_
2585+
~loc:(mk_loc expr.pexp_loc.loc_start body.pexp_loc.loc_end)
2586+
~arity:None Asttypes.Nolabel None
2587+
(Ast_helper.Pat.constraint_ pat typ)
2588+
body
2589+
in
2590+
let msg =
2591+
Doc.breakable_group ~force_break:true
2592+
(Doc.concat
2593+
[
2594+
Doc.text
2595+
"Did you mean to annotate the parameter type or the return \
2596+
type?";
2597+
Doc.indent
2598+
(Doc.concat
2599+
[
2600+
Doc.line;
2601+
Doc.text "1) ";
2602+
ResPrinter.print_expression arrow1 CommentTable.empty;
2603+
Doc.line;
2604+
Doc.text "2) ";
2605+
ResPrinter.print_expression arrow2 CommentTable.empty;
2606+
]);
2607+
])
2608+
|> Doc.to_string ~width:80
2609+
in
2610+
Parser.err ~start_pos:expr.pexp_loc.loc_start
2611+
~end_pos:body.pexp_loc.loc_end p (Diagnostics.message msg);
2612+
arrow1
26052613
| _ ->
26062614
let loc = mk_loc expr.pexp_loc.loc_start typ.ptyp_loc.loc_end in
26072615
let expr = Ast_helper.Exp.constraint_ ~loc expr typ in

tests/syntax_tests/data/parsing/grammar/expressions/arrow.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ let un = (():u)
103103
type d<'a,'b> = ('a,'b)
104104
let c = (): d<'a,'b> => (1,2)
105105

106+
let arr = (): array<nullable<int>> => []
107+
106108
let fn = f => f;
107109
type f = int => unit;
108110
let a = fn(_ => (): f);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ type nonrec u = unit
7474
let un = (() : u)
7575
type nonrec ('a, 'b) d = ('a * 'b)
7676
let c [arity:1]() = ((1, 2) : ('a, 'b) d)
77+
let arr () = ([||] : int nullable array)
7778
let fn [arity:1]f = f
7879
type nonrec f = int -> unit (a:1)
7980
let a = fn (fun [arity:1]_ -> () : f)

tests/syntax_tests/data/printer/expr/expected/fun.res.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,3 +356,5 @@ let query = (~url, ()): (unit => unit => unit => unit) => {
356356
let f = a => b => a + b
357357
let f = (a, b) => (b, c) => a + b + c + d
358358
let f = (a, b) => (b, c) => (e, f, g) => a + b + c + d + e + f + g
359+
360+
let unitConstraint = (): array<nullable<int>> => []

tests/syntax_tests/data/printer/expr/fun.res

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,5 @@ let query = (~url, ()): (unit => unit => unit => unit) => {
297297
let f = (. a) => (. b) => a + b
298298
let f = (. a, b) => (. b, c) => a + b + c + d
299299
let f = (. a, b) => (. b , c) => (. e , f, g) => a + b + c + d + e + f + g
300+
301+
let unitConstraint = (): array<nullable<int>> => []

0 commit comments

Comments
 (0)