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

Commit dd8339a

Browse files
Sehun0819sehooncristianoc
authored
parser crashes on polymorphic variant type (#540)
* fix crash on polymorphic variant type * add testcase * fix pattern matching priority in parsePolymorphicVariantType * Put parseTagName at the toplevel. Co-authored-by: sehoon <sehoon@sehoonui-MacBookPro.local> Co-authored-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
1 parent af00a46 commit dd8339a

File tree

4 files changed

+30
-14
lines changed

4 files changed

+30
-14
lines changed

src/res_core.ml

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4968,19 +4968,7 @@ and parsePolymorphicVariantType ~attrs p =
49684968
Parser.optional p Bar |> ignore;
49694969
let rowField = parseTagSpecFull p in
49704970
let rowFields = parseTagSpecFulls p in
4971-
let tagNames =
4972-
if p.token == GreaterThan
4973-
then begin
4974-
Parser.next p;
4975-
let rec loop p = match p.Parser.token with
4976-
| Rbracket -> []
4977-
| _ ->
4978-
let (ident, _loc) = parseHashIdent ~startPos:p.startPos p in
4979-
ident :: loop p
4980-
in
4981-
loop p
4982-
end
4983-
else [] in
4971+
let tagNames = parseTagNames p in
49844972
let variant =
49854973
let loc = mkLoc startPos p.prevEndPos in
49864974
Ast_helper.Typ.variant ~attrs ~loc (rowField :: rowFields) Closed (Some tagNames) in
@@ -4995,6 +4983,20 @@ and parsePolymorphicVariantType ~attrs p =
49954983
Parser.expect Rbracket p;
49964984
variant
49974985

4986+
and parseTagName p =
4987+
match p.Parser.token with
4988+
| Hash ->
4989+
let (ident, _loc) = parseHashIdent ~startPos:p.startPos p in
4990+
Some ident
4991+
| _ -> None
4992+
4993+
and parseTagNames p =
4994+
if p.Parser.token == GreaterThan then
4995+
(Parser.next p;
4996+
parseRegion p ~grammar:Grammar.TagNames ~f:parseTagName)
4997+
else
4998+
[]
4999+
49985000
and parseTagSpecFulls p =
49995001
match p.Parser.token with
50005002
| Rbracket ->
@@ -6449,4 +6451,4 @@ let parseSpecification p : Parsetree.signature =
64496451

64506452
(* module structure on the file level *)
64516453
let parseImplementation p : Parsetree.structure =
6452-
parseRegion p ~grammar:Grammar.Implementation ~f:parseStructureItemRegion
6454+
parseRegion p ~grammar:Grammar.Implementation ~f:parseStructureItemRegion

src/res_grammar.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ type t =
5858
| JsFfiImport
5959
| Pattern
6060
| AttributePayload
61+
| TagNames
6162

6263
let toString = function
6364
| OpenDescription -> "an open description"
@@ -118,6 +119,7 @@ let toString = function
118119
| Pattern -> "pattern"
119120
| ExprFor -> "a for expression"
120121
| AttributePayload -> "an attribute payload"
122+
| TagNames -> "tag names"
121123

122124
let isSignatureItemStart = function
123125
| Token.At
@@ -336,6 +338,7 @@ let isListElement grammar token =
336338
| JsxAttribute -> isJsxAttributeStart token
337339
| JsFfiImport -> isJsFfiImportStart token
338340
| AttributePayload -> token = Lparen
341+
| TagNames -> token = Hash
339342
| _ -> false
340343

341344
let isListTerminator grammar token =
@@ -361,6 +364,7 @@ let isListTerminator grammar token =
361364
| PackageConstraint, token when token <> And -> true
362365
| ConstructorDeclaration, token when token <> Bar -> true
363366
| AttributePayload, Rparen -> true
367+
| TagNames, Rbracket -> true
364368

365369
| _ -> false
366370

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
Syntax error!
3+
tests/parsing/infiniteLoops/polymorphicVariantType.res:1:14
4+
5+
1 │ type x = [<y>
6+
7+
Did you forget a `]` here?
8+
9+
type nonrec x = [< y]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
type x = [<y>

0 commit comments

Comments
 (0)