Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit a0d7689

Browse files
author
Iwan
committed
Improve diagnostics for missing tilde in labeled parameters.
1) In certain scenarios there was no error: `let f = (x, y=2, z) => x + y + z`. Results in an assertion failure in the typechecker. 2) Streamlines the language in the diagnostic across expressions and types. Fixes #216
1 parent c876721 commit a0d7689

File tree

4 files changed

+55
-8
lines changed

4 files changed

+55
-8
lines changed

src/res_core.ml

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ module Recover = struct
2626
let defaultPattern () =
2727
let id = Location.mknoloc "rescript.patternhole" in
2828
Ast_helper.Pat.extension (id, PStr [])
29-
(* Ast_helper.Pat.any () *)
3029

3130
let defaultModuleExpr () = Ast_helper.Mod.structure []
3231
let defaultModuleType () = Ast_helper.Mty.signature []
@@ -104,6 +103,12 @@ Solution: directly use `concat`."
104103
"A type declaration's name cannot contain a module access. Did you mean `" ^ (Longident.last longident) ^"`?"
105104

106105
let tupleSingleElement = "A tuple needs at least two elements"
106+
107+
let missingTildeLabeledParameter name =
108+
if name = "" then
109+
"A labeled parameter starts with a `~`."
110+
else
111+
("A labeled parameter starts with a `~`. Did you mean: `~" ^ name ^ "`?")
107112
end
108113

109114

@@ -1595,6 +1600,10 @@ and parseParameter p =
15951600
let lidents = parseLidentList p in
15961601
Some (TypeParameter {uncurried; attrs; locs = lidents; pos = startPos})
15971602
) else (
1603+
let hasTilde = match p.token with
1604+
| Tilde -> true
1605+
| _ -> false
1606+
in
15981607
let (attrs, lbl, pat) = match p.Parser.token with
15991608
| Tilde ->
16001609
Parser.next p;
@@ -1641,11 +1650,18 @@ and parseParameter p =
16411650
in
16421651
match p.Parser.token with
16431652
| Equal ->
1653+
if not hasTilde then (
1654+
let msg = match pat.ppat_desc with
1655+
| Ppat_var var -> ErrorMessages.missingTildeLabeledParameter var.txt
1656+
| _ -> ErrorMessages.missingTildeLabeledParameter ""
1657+
in
1658+
Parser.err ~startPos p (Diagnostics.message msg)
1659+
);
16441660
Parser.next p;
16451661
let lbl = match lbl with
1646-
| Asttypes.Labelled lblName -> Asttypes.Optional lblName
1647-
| Asttypes.Optional _ as lbl -> lbl
1648-
| Asttypes.Nolabel -> Asttypes.Nolabel
1662+
| Asttypes.Labelled lblName ->
1663+
Asttypes.Optional lblName
1664+
| lbl -> lbl
16491665
in
16501666
begin match p.Parser.token with
16511667
| Question ->
@@ -3848,9 +3864,9 @@ and parseTypeParameter p =
38483864
begin match p.token with
38493865
| Colon ->
38503866
let () =
3851-
let error = Diagnostics.message
3852-
("Parameter names start with a `~`, like: ~" ^ name)
3853-
in
3867+
let error = Diagnostics.message (
3868+
ErrorMessages.missingTildeLabeledParameter name
3869+
) in
38543870
Parser.err ~startPos:loc.loc_start ~endPos:loc.loc_end p error
38553871
in
38563872
Parser.next p;

tests/parsing/errors/other/__snapshots__/parse.spec.js.snap

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,34 @@ module M = struct ;;match l with | None -> [] | Some l -> l ## prop end
3232
I'm not sure what to parse here when looking at \\"}\\".
3333
3434
35+
========================================================"
36+
`;
37+
38+
exports[`labelledParameters.res 1`] = `
39+
"=====Parsetree==========================================
40+
let f x y z = (x + y) + z
41+
type nonrec f = x:int -> y:int -> int
42+
=====Errors=============================================
43+
44+
Syntax error!
45+
parsing/errors/other/labelledParameters.res:1:13-14
46+
1 │ let f = (x, y=2, z) => x + y + z
47+
2 │
48+
3 │ type f = (x: int, y: int) => int
49+
50+
A labeled parameter starts with a \`~\`. Did you mean: \`~y\`?
51+
52+
53+
Syntax error!
54+
parsing/errors/other/labelledParameters.res:3:11
55+
1 │ let f = (x, y=2, z) => x + y + z
56+
2 │
57+
3 │ type f = (x: int, y: int) => int
58+
4 │
59+
60+
A labeled parameter starts with a \`~\`. Did you mean: \`~x\`?
61+
62+
3563
========================================================"
3664
`;
3765

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
let f = (x, y=2, z) => x + y + z
2+
3+
type f = (x: int, y: int) => int

tests/parsing/errors/typeDef/__snapshots__/parse.spec.js.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ type nonrec draw = stroke:pencil -> unit
100100
1 │ type draw = (stroke: pencil) => unit
101101
2 │
102102
103-
Parameter names start with a \`~\`, like: ~stroke
103+
A labeled parameter starts with a \`~\`. Did you mean: \`~stroke\`?
104104
105105
106106
========================================================"

0 commit comments

Comments
 (0)