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

Commit a4a5bda

Browse files
committed
Fix issue with attributes on single-field optional record declaration.
Fixes #627
1 parent 2ccf916 commit a4a5bda

File tree

4 files changed

+63
-13
lines changed

4 files changed

+63
-13
lines changed

src/res_core.ml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4286,6 +4286,7 @@ and parseFieldDeclaration p =
42864286
match p.token with
42874287
| _ -> parseLident p
42884288
in
4289+
let optional = parseOptionalLabel p in
42894290
let name = Location.mkloc lident loc in
42904291
let typ =
42914292
match p.Parser.token with
@@ -4296,7 +4297,7 @@ and parseFieldDeclaration p =
42964297
Ast_helper.Typ.constr ~loc:name.loc {name with txt = Lident name.txt} []
42974298
in
42984299
let loc = mkLoc startPos typ.ptyp_loc.loc_end in
4299-
Ast_helper.Type.field ~attrs ~loc ~mut name typ
4300+
(optional, Ast_helper.Type.field ~attrs ~loc ~mut name typ)
43004301

43014302
and parseFieldDeclarationRegion p =
43024303
let startPos = p.Parser.startPos in
@@ -4309,6 +4310,7 @@ and parseFieldDeclarationRegion p =
43094310
| Lident _ ->
43104311
let lident, loc = parseLident p in
43114312
let name = Location.mkloc lident loc in
4313+
(* XXX *)
43124314
let optional = parseOptionalLabel p in
43134315
let typ =
43144316
match p.Parser.token with
@@ -4488,7 +4490,10 @@ and parseConstrDeclArgs p =
44884490
~closing:Rbrace ~f:parseFieldDeclarationRegion p
44894491
| attrs ->
44904492
let first =
4491-
let field = parseFieldDeclaration p in
4493+
let optional, field = parseFieldDeclaration p in
4494+
let attrs =
4495+
if optional then optionalAttr :: attrs else attrs
4496+
in
44924497
Parser.expect Comma p;
44934498
{field with Parsetree.pld_attributes = attrs}
44944499
in
@@ -4885,13 +4890,15 @@ and parseRecordOrObjectDecl p =
48854890
| _ ->
48864891
Parser.leaveBreadcrumb p Grammar.RecordDecl;
48874892
let fields =
4893+
(* XXX *)
48884894
match attrs with
48894895
| [] ->
48904896
parseCommaDelimitedRegion ~grammar:Grammar.FieldDeclarations
48914897
~closing:Rbrace ~f:parseFieldDeclarationRegion p
48924898
| attr :: _ as attrs ->
48934899
let first =
4894-
let field = parseFieldDeclaration p in
4900+
let optional, field = parseFieldDeclaration p in
4901+
let attrs = if optional then optionalAttr :: attrs else attrs in
48954902
Parser.optional p Comma |> ignore;
48964903
{
48974904
field with
Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,45 @@
1-
2-
Syntax error!
3-
tests/parsing/grammar/expressions/record.res:52:32
4-
5-
50 │ type multipleWithAttrs = {x:int, @attr y?: string}
6-
51 │
7-
52 │ type singleWithAttrs = {@attr y?: string}
8-
9-
I'm not sure what to parse here when looking at "?".
10-
1+
let r = { a = expr }
2+
let r = { a = expr }
3+
let r = { Parsetree.pexp_attributes = [||]; Parsetree.loc = loc }
4+
let r = { a; b; c }
5+
let r = { A.a = a; b }
6+
let r = { A.a = a; b; C.c = c }
7+
let r = { Parsetree.pexp_attributes = pexp_attributes; Parsetree.loc = loc }
8+
let r = { Parsetree.pexp_attributes = pexp_attributes; Parsetree.loc = loc }
9+
let r = { a = (expr : int); b = (x : string) }
10+
let r = { expr with pexp_attributes = [||] }
11+
let r = { expr with pexp_attributes = [||]; pexp_loc = loc }
12+
let r = { expr with pexp_attributes = [||] }
13+
let r = { (make () : myRecord) with foo = bar }
14+
let r = { (make () : myRecord) with foo = bar }
15+
let r =
16+
{
17+
x = ((None)[@ns.optional ]);
18+
y = ((None)[@ns.optional ]);
19+
z = (((None : tt))[@ns.optional ])
20+
}
21+
let z name = { name = ((name)[@ns.optional ]); x = 3 }
22+
let z name = { name = ((name)[@ns.optional ]); x = 3 }
23+
let z name = { name; x = ((x)[@ns.optional ]) }
24+
let zz name = { name; x = ((x)[@ns.optional ]) }
25+
let _ =
26+
match z with
27+
| { x = ((None)[@ns.optional ]); y = ((None)[@ns.optional ]);
28+
z = (((None : tt))[@ns.optional ]) } -> 11
29+
| { name = ((name)[@ns.optional ]); x = 3 } -> 42
30+
| { name = ((name)[@ns.optional ]); x = 3 } -> 4242
31+
| { x = ((None)[@ns.optional ]); y = ((None)[@ns.optional ]);
32+
z = (((None : tt))[@ns.optional ]) } -> 11
33+
| { name = ((name)[@ns.optional ]); x = 3 } -> 42
34+
| { name = ((name)[@ns.optional ]); x = 3 } -> 4242
35+
type nonrec tt = {
36+
x: int ;
37+
y: string [@ns.opttinal ]}
38+
type nonrec ttt = {
39+
x: int ;
40+
y: string [@ns.optional ]}
41+
type nonrec multipleWithAttrs = {
42+
x: int ;
43+
y: string [@ns.optional ][@attr ]}
44+
type nonrec singleWithAttrs = {
45+
y: string [@ns.optional ][@attr ]}

tests/printer/typeDef/expected/record.res.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ type user = {
6666
@attrSuperLongNaaaaaaaaaaaaaaameSooooooooLong
6767
hairStyle: Hair.t,
6868
}
69+
70+
type multipleWithAttrs = {x: int, @attr y?: string}
71+
72+
type singleWithAttrs = {@attr y?: string}

tests/printer/typeDef/record.res

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@ type user = {
5151
hairStyle: Hair.t,
5252
@attrAbove @attrSuperLongNaaaaaaaaaaaaaaameSooooooooLong @attrSuperLongNaaaaaaaaaaaaaaameSooooooooLong hairStyle: Hair.t
5353
}
54+
55+
type multipleWithAttrs = {x:int, @attr y?: string}
56+
57+
type singleWithAttrs = {@attr y?: string}

0 commit comments

Comments
 (0)