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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#### :bug: Bug fix

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

#### :memo: Documentation

Expand Down
82 changes: 45 additions & 37 deletions compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2554,54 +2554,62 @@ and over_parse_constrained_or_coerced_or_arrow_expression p expr =
| EqualGreater ->
Parser.next p;
let body = parse_expr p in
let pat =
let pat, expr_is_unit =
match expr.pexp_desc with
| Pexp_ident longident ->
Ast_helper.Pat.var ~loc:expr.pexp_loc
(Location.mkloc
(Longident.flatten longident.txt |> String.concat ".")
longident.loc)
( Ast_helper.Pat.var ~loc:expr.pexp_loc
(Location.mkloc
(Longident.flatten longident.txt |> String.concat ".")
longident.loc),
false )
| Pexp_construct (({txt = Longident.Lident "()"} as lid), None) ->
(Ast_helper.Pat.construct ~loc:expr.pexp_loc lid None, true)
(* TODO: can we convert more expressions to patterns?*)
| _ ->
Ast_helper.Pat.var ~loc:expr.pexp_loc
(Location.mkloc "pattern" expr.pexp_loc)
( Ast_helper.Pat.var ~loc:expr.pexp_loc
(Location.mkloc "pattern" expr.pexp_loc),
false )
in
let arrow1 =
Ast_helper.Exp.fun_
~loc:(mk_loc expr.pexp_loc.loc_start body.pexp_loc.loc_end)
~arity:None Asttypes.Nolabel None pat
(Ast_helper.Exp.constraint_ body typ)
in
let arrow2 =
Ast_helper.Exp.fun_
~loc:(mk_loc expr.pexp_loc.loc_start body.pexp_loc.loc_end)
~arity:None Asttypes.Nolabel None
(Ast_helper.Pat.constraint_ pat typ)
body
in
let msg =
Doc.breakable_group ~force_break:true
(Doc.concat
[
Doc.text
"Did you mean to annotate the parameter type or the return \
type?";
Doc.indent
(Doc.concat
[
Doc.line;
Doc.text "1) ";
ResPrinter.print_expression arrow1 CommentTable.empty;
Doc.line;
Doc.text "2) ";
ResPrinter.print_expression arrow2 CommentTable.empty;
]);
])
|> Doc.to_string ~width:80
in
Parser.err ~start_pos:expr.pexp_loc.loc_start
~end_pos:body.pexp_loc.loc_end p (Diagnostics.message msg);
arrow1
(* When the "expr" was `()`, the colon must apply to the return type, so
skip the ambiguity diagnostic and keep the parameter as unit. *)
if expr_is_unit then arrow1
else
let arrow2 =
Ast_helper.Exp.fun_
~loc:(mk_loc expr.pexp_loc.loc_start body.pexp_loc.loc_end)
~arity:None Asttypes.Nolabel None
(Ast_helper.Pat.constraint_ pat typ)
body
in
let msg =
Doc.breakable_group ~force_break:true
(Doc.concat
[
Doc.text
"Did you mean to annotate the parameter type or the return \
type?";
Doc.indent
(Doc.concat
[
Doc.line;
Doc.text "1) ";
ResPrinter.print_expression arrow1 CommentTable.empty;
Doc.line;
Doc.text "2) ";
ResPrinter.print_expression arrow2 CommentTable.empty;
]);
])
|> Doc.to_string ~width:80
in
Parser.err ~start_pos:expr.pexp_loc.loc_start
~end_pos:body.pexp_loc.loc_end p (Diagnostics.message msg);
arrow1
| _ ->
let loc = mk_loc expr.pexp_loc.loc_start typ.ptyp_loc.loc_end in
let expr = Ast_helper.Exp.constraint_ ~loc expr typ in
Expand Down
2 changes: 2 additions & 0 deletions tests/syntax_tests/data/parsing/grammar/expressions/arrow.res
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ let un = (():u)
type d<'a,'b> = ('a,'b)
let c = (): d<'a,'b> => (1,2)

let arr = (): array<nullable<int>> => []

let fn = f => f;
type f = int => unit;
let a = fn(_ => (): f);
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type nonrec u = unit
let un = (() : u)
type nonrec ('a, 'b) d = ('a * 'b)
let c [arity:1]() = ((1, 2) : ('a, 'b) d)
let arr () = ([||] : int nullable array)
let fn [arity:1]f = f
type nonrec f = int -> unit (a:1)
let a = fn (fun [arity:1]_ -> () : f)
2 changes: 2 additions & 0 deletions tests/syntax_tests/data/printer/expr/expected/fun.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,5 @@ let query = (~url, ()): (unit => unit => unit => unit) => {
let f = a => b => a + b
let f = (a, b) => (b, c) => a + b + c + d
let f = (a, b) => (b, c) => (e, f, g) => a + b + c + d + e + f + g

let unitConstraint = (): array<nullable<int>> => []
2 changes: 2 additions & 0 deletions tests/syntax_tests/data/printer/expr/fun.res
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,5 @@ let query = (~url, ()): (unit => unit => unit => unit) => {
let f = (. a) => (. b) => a + b
let f = (. a, b) => (. b, c) => a + b + c + d
let f = (. a, b) => (. b , c) => (. e , f, g) => a + b + c + d + e + f + g

let unitConstraint = (): array<nullable<int>> => []
Loading