Skip to content

Commit d8e2f21

Browse files
authored
Parser: recover on missing union case field types (#17455)
* Parser: recover on missing union case field types * Release notes
1 parent d2d38e3 commit d8e2f21

File tree

8 files changed

+148
-9
lines changed

8 files changed

+148
-9
lines changed

docs/release-notes/.FSharp.Compiler.Service/9.0.100.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
### Added
1010

1111
* Support for nullable reference types ([PR #15181](https://github.com/dotnet/fsharp/pull/15181))
12-
* Parser: recover on missing union case fields ([#17452](https://github.com/dotnet/fsharp/pull/17452))
12+
* Parser: recover on missing union case fields (PR [#17452](https://github.com/dotnet/fsharp/pull/17452))
13+
* Parser: recover on missing union case field types (PR [#17455](https://github.com/dotnet/fsharp/pull/17455))
1314
* Sink: report function domain type ([PR #17470](https://github.com/dotnet/fsharp/pull/17470))
1415

1516
### Changed

src/Compiler/pars.fsy

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) ->
168168
%type <SynExpr> argExpr
169169
%type <SynExpr> declExprBlock
170170
%type <SynPat> headBindingPattern
171+
%type <SynType> appTypeNullableInParens
171172
%type <SynType> atomTypeNonAtomicDeprecated
172173
%type <SynExpr> atomicExprAfterType
173174
%type <SynExpr> typedSequentialExprBlock
@@ -2883,27 +2884,35 @@ unionCaseReprElements:
28832884
field :: fields, unionRanges mStar mFields }
28842885

28852886
| unionCaseReprElement %prec prec_toptuptyptail_prefix
2886-
{ [$1], rhs parseState 1 }
2887+
{ [$1], $1.Range }
28872888

28882889
unionCaseReprElement:
28892890
| ident COLON appTypeNullableInParens
2890-
{ let xmlDoc = grabXmlDoc(parseState, [], 1)
2891-
let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc
2891+
{ let xmlDoc = grabXmlDoc (parseState, [], 1)
2892+
let mId = rhs parseState 1
2893+
let mWhole = unionRanges mId $3.Range |> unionRangeWithXmlDoc xmlDoc
28922894
mkSynNamedField ($1, $3, xmlDoc, mWhole) }
28932895

2896+
| ident COLON recover
2897+
{ let xmlDoc = grabXmlDoc (parseState, [], 1)
2898+
let mColon = rhs parseState 2
2899+
let ty = SynType.FromParseError mColon.EndRange
2900+
let mWhole = rhs2 parseState 1 2 |> unionRangeWithXmlDoc xmlDoc
2901+
mkSynNamedField ($1, ty, xmlDoc, mWhole) }
2902+
28942903
| appTypeNullableInParens
2895-
{ let xmlDoc = grabXmlDoc(parseState, [], 1)
2904+
{ let xmlDoc = grabXmlDoc (parseState, [], 1)
28962905
mkSynAnonField ($1, xmlDoc) }
28972906

28982907
| ident COLON invalidUseOfAppTypeFunction
2899-
{ let xmlDoc = grabXmlDoc(parseState, [], 1)
2908+
{ let xmlDoc = grabXmlDoc (parseState, [], 1)
29002909
let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc
2901-
reportParseErrorAt ($3 : SynType).Range (FSComp.SR.tcUnexpectedFunTypeInUnionCaseField())
2910+
reportParseErrorAt ($3: SynType).Range (FSComp.SR.tcUnexpectedFunTypeInUnionCaseField ())
29022911
mkSynNamedField ($1, $3, xmlDoc, mWhole) }
29032912

29042913
| invalidUseOfAppTypeFunction
2905-
{ let xmlDoc = grabXmlDoc(parseState, [], 1)
2906-
reportParseErrorAt ($1 : SynType).Range (FSComp.SR.tcUnexpectedFunTypeInUnionCaseField())
2914+
{ let xmlDoc = grabXmlDoc (parseState, [], 1)
2915+
reportParseErrorAt ($1: SynType).Range (FSComp.SR.tcUnexpectedFunTypeInUnionCaseField ())
29072916
mkSynAnonField ($1, xmlDoc) }
29082917

29092918
unionCaseRepr:
@@ -5981,11 +5990,13 @@ invalidUseOfAppTypeFunction:
59815990
{ let mArrow = rhs parseState 2
59825991
let m = unionRanges (rhs2 parseState 1 2) $3.Range
59835992
SynType.Fun($1, $3, m, { ArrowRange = mArrow }) }
5993+
59845994
| appTypeWithoutNull RARROW recover
59855995
{ let mArrow = rhs parseState 2
59865996
let ty = SynType.FromParseError(mArrow.EndRange)
59875997
let m = rhs2 parseState 1 2
59885998
SynType.Fun($1, ty, m, { ArrowRange = mArrow }) }
5999+
59896000
| appTypeWithoutNull RARROW RARROW invalidUseOfAppTypeFunction
59906001
{ let mArrow1 = rhs parseState 2
59916002
let mArrow2 = rhs parseState 3
@@ -5994,6 +6005,7 @@ invalidUseOfAppTypeFunction:
59946005
let m1 = unionRanges $1.Range $4.Range
59956006
let m2 = unionRanges mArrow2 $4.Range
59966007
SynType.Fun($1, SynType.Fun(ty, $4, m2, { ArrowRange = mArrow2 }), m1, { ArrowRange = mArrow1 }) }
6008+
59976009
| appTypeWithoutNull RARROW appTypeWithoutNull
59986010
{ let mArrow = rhs parseState 2
59996011
let m = rhs2 parseState 1 3
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Module
2+
3+
type U =
4+
| A of i: int
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/Type/Union - Field 01.fs", false, QualifiedNameOfFile Module, [],
4+
[],
5+
[SynModuleOrNamespace
6+
([Module], false, NamedModule,
7+
[Types
8+
([SynTypeDefn
9+
(SynComponentInfo
10+
([], None, [], [U],
11+
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
12+
false, None, (3,5--3,6)),
13+
Simple
14+
(Union
15+
(None,
16+
[SynUnionCase
17+
([], SynIdent (A, None),
18+
Fields
19+
[SynField
20+
([], false, Some i,
21+
LongIdent (SynLongIdent ([int], [], [None])),
22+
false,
23+
PreXmlDoc ((4,11), FSharp.Compiler.Xml.XmlDocCollector),
24+
None, (4,11--4,17), { LeadingKeyword = None
25+
MutableKeyword = None })],
26+
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
27+
None, (4,6--4,17), { BarRange = Some (4,4--4,5) })],
28+
(4,4--4,17)), (4,4--4,17)), [], None, (3,5--4,17),
29+
{ LeadingKeyword = Type (3,0--3,4)
30+
EqualsRange = Some (3,7--3,8)
31+
WithKeyword = None })], (3,0--4,17))],
32+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
33+
(1,0--4,17), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
34+
{ ConditionalDirectives = []
35+
CodeComments = [] }, set []))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Module
2+
3+
type U =
4+
| A of i:
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/Type/Union - Field 02.fs", false, QualifiedNameOfFile Module, [],
4+
[],
5+
[SynModuleOrNamespace
6+
([Module], false, NamedModule,
7+
[Types
8+
([SynTypeDefn
9+
(SynComponentInfo
10+
([], None, [], [U],
11+
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
12+
false, None, (3,5--3,6)),
13+
Simple
14+
(Union
15+
(None,
16+
[SynUnionCase
17+
([], SynIdent (A, None),
18+
Fields
19+
[SynField
20+
([], false, Some i, FromParseError (4,13--4,13),
21+
false,
22+
PreXmlDoc ((4,11), FSharp.Compiler.Xml.XmlDocCollector),
23+
None, (4,11--4,13), { LeadingKeyword = None
24+
MutableKeyword = None })],
25+
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
26+
None, (4,6--4,13), { BarRange = Some (4,4--4,5) })],
27+
(4,4--4,13)), (4,4--4,13)), [], None, (3,5--4,13),
28+
{ LeadingKeyword = Type (3,0--3,4)
29+
EqualsRange = Some (3,7--3,8)
30+
WithKeyword = None })], (3,0--4,13))],
31+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
32+
(1,0--4,13), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
33+
{ ConditionalDirectives = []
34+
CodeComments = [] }, set []))
35+
36+
(5,0)-(5,0) parse error Incomplete structured construct at or before this point in union case
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Module
2+
3+
type U =
4+
| A of i: * int
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/Type/Union - Field 03.fs", false, QualifiedNameOfFile Module, [],
4+
[],
5+
[SynModuleOrNamespace
6+
([Module], false, NamedModule,
7+
[Types
8+
([SynTypeDefn
9+
(SynComponentInfo
10+
([], None, [], [U],
11+
PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector),
12+
false, None, (3,5--3,6)),
13+
Simple
14+
(Union
15+
(None,
16+
[SynUnionCase
17+
([], SynIdent (A, None),
18+
Fields
19+
[SynField
20+
([], false, Some i, FromParseError (4,13--4,13),
21+
false,
22+
PreXmlDoc ((4,11), FSharp.Compiler.Xml.XmlDocCollector),
23+
None, (4,11--4,13), { LeadingKeyword = None
24+
MutableKeyword = None });
25+
SynField
26+
([], false, None,
27+
LongIdent (SynLongIdent ([int], [], [None])),
28+
false,
29+
PreXmlDoc ((4,16), FSharp.Compiler.Xml.XmlDocCollector),
30+
None, (4,16--4,19), { LeadingKeyword = None
31+
MutableKeyword = None })],
32+
PreXmlDoc ((4,4), FSharp.Compiler.Xml.XmlDocCollector),
33+
None, (4,6--4,19), { BarRange = Some (4,4--4,5) })],
34+
(4,4--4,19)), (4,4--4,19)), [], None, (3,5--4,19),
35+
{ LeadingKeyword = Type (3,0--3,4)
36+
EqualsRange = Some (3,7--3,8)
37+
WithKeyword = None })], (3,0--4,19))],
38+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
39+
(1,0--4,19), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
40+
{ ConditionalDirectives = []
41+
CodeComments = [] }, set []))
42+
43+
(4,14)-(4,15) parse error Unexpected symbol '*' in union case

0 commit comments

Comments
 (0)