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

Commit dc53370

Browse files
Don't parse Int token with suffices as hash ident for poly variants (#408)
* Don't parse Int token with suffices as hash ident for poly variants `#10s` should not be accepted as a numeric polyvariant identifier. Fixes #407 * Tweak `variantIdent` error message based on feedback from bloodyowl Co-authored-by: Matthias Le Brun <bloodyowl@icloud.com> * Update hashIdent error tests * Add printer test to verify that int tokens with suffix aren't printed as numeric polyvars * Refine error message for numeric polyvars followed by a letter. Co-authored-by: Matthias Le Brun <bloodyowl@icloud.com>
1 parent 945a7a6 commit dc53370

File tree

5 files changed

+66
-3
lines changed

5 files changed

+66
-3
lines changed

src/res_core.ml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Explanation: since records have a known, fixed shape, a spread like `{a, ...b}`
7777
Explanation: lists are singly-linked list, where a node contains a value and points to the next node. `list[a, ...bc]` efficiently creates a new item and links `bc` as its next nodes. `[...bc, a]` would be expensive, as it'd need to traverse `bc` and prepend each item to `a` one by one. We therefore disallow such syntax sugar.\n\
7878
Solution: directly use `concat`."
7979

80-
let variantIdent = "A polymorphic variant (e.g. #id) must start with an alphabetical letter."
80+
let variantIdent = "A polymorphic variant (e.g. #id) must start with an alphabetical letter or be a number (e.g. #742)"
8181

8282
let experimentalIfLet expr =
8383
let switchExpr = {expr with Parsetree.pexp_attributes = []} in
@@ -124,6 +124,9 @@ Solution: directly use `concat`."
124124

125125
let sameTypeSpread =
126126
"You're using a ... spread without extra fields. This is the same type."
127+
128+
let polyVarIntWithSuffix number =
129+
"A numeric polymorphic variant cannot be followed by a letter. Did you mean `#" ^ number ^ "`?"
127130
end
128131

129132

@@ -696,7 +699,12 @@ let parseHashIdent ~startPos p =
696699
Parser.next p;
697700
let text = if p.mode = ParseForTypeChecker then parseStringLiteral text else text in
698701
(text, mkLoc startPos p.prevEndPos)
699-
| Int {i} ->
702+
| Int {i; suffix} ->
703+
let () = match suffix with
704+
| Some _ ->
705+
Parser.err p (Diagnostics.message (ErrorMessages.polyVarIntWithSuffix i))
706+
| None -> ()
707+
in
700708
Parser.next p;
701709
(i, mkLoc startPos p.prevEndPos)
702710
| _ ->
@@ -1202,7 +1210,12 @@ let rec parsePattern ?(alias=true) ?(or_=true) p =
12021210
Parser.next p;
12031211
let text = if p.mode = ParseForTypeChecker then parseStringLiteral text else text in
12041212
(text, mkLoc startPos p.prevEndPos)
1205-
| Int {i} ->
1213+
| Int {i; suffix} ->
1214+
let () = match suffix with
1215+
| Some _ ->
1216+
Parser.err p (Diagnostics.message (ErrorMessages.polyVarIntWithSuffix i))
1217+
| None -> ()
1218+
in
12061219
Parser.next p;
12071220
(i, mkLoc startPos p.prevEndPos)
12081221
| _ ->
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
Syntax error!
3+
tests/parsing/errors/other/hashIdent.res:1:10-12
4+
5+
1 │ let x = #10s
6+
2 │
7+
3 │ type t = [ #red | #10s ]
8+
9+
A numeric polymorphic variant cannot be followed by a letter. Did you mean `#10`?
10+
11+
12+
Syntax error!
13+
tests/parsing/errors/other/hashIdent.res:3:20-22
14+
15+
1 │ let x = #10s
16+
2 │
17+
3 │ type t = [ #red | #10s ]
18+
4 │
19+
5 │ switch x {
20+
21+
A numeric polymorphic variant cannot be followed by a letter. Did you mean `#10`?
22+
23+
24+
Syntax error!
25+
tests/parsing/errors/other/hashIdent.res:6:4-6
26+
27+
4 │
28+
5 │ switch x {
29+
6 │ | #10s => ()
30+
7 │ }
31+
8 │
32+
33+
A numeric polymorphic variant cannot be followed by a letter. Did you mean `#10`?
34+
35+
let x = `10
36+
type nonrec t = [ `red | `10 ]
37+
;;match x with | `10 -> ()
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
let x = #10s
2+
3+
type t = [ #red | #10s ]
4+
5+
switch x {
6+
| #10s => ()
7+
}

tests/printer/typexpr/expected/variant.res.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,6 @@ type t = [
112112
| #1(string)
113113
| #2(int, string)
114114
]
115+
116+
// don't pick int with suffix as numeric polyvar
117+
type t = [#"10s" | #"20t"]

tests/printer/typexpr/variant.res

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,6 @@ type t = [
106106
| #1(string)
107107
| #2(int, string)
108108
]
109+
110+
// don't pick int with suffix as numeric polyvar
111+
type t = [#"10s" | #"20t" ]

0 commit comments

Comments
 (0)