Skip to content

Commit 4e8a29a

Browse files
authored
Parser: recover on missing types in patterns (#15056)
1 parent f10c3e5 commit 4e8a29a

40 files changed

+832
-40
lines changed

src/Compiler/pars.fsy

Lines changed: 81 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3020,6 +3020,11 @@ simplePattern:
30203020
| simplePattern COLON typeWithTypeConstraints
30213021
{ SynPat.Typed($1, $3, lhs parseState) }
30223022

3023+
| simplePattern COLON recover
3024+
{ let mColon = rhs parseState 2
3025+
let ty = SynType.FromParseError(mColon.EndRange)
3026+
SynPat.Typed($1, ty, unionRanges $1.Range mColon) }
3027+
30233028
| attributes simplePattern %prec paren_pat_attribs
30243029
{ SynPat.Attrib($2, $1, lhs parseState) }
30253030

@@ -3341,9 +3346,14 @@ parenPattern:
33413346
| conjParenPatternElements
33423347
{ SynPat.Ands(List.rev $1, rhs2 parseState 1 3) }
33433348

3344-
| parenPattern COLON typeWithTypeConstraints %prec paren_pat_colon
3345-
{ let mLhs = lhs parseState
3346-
SynPat.Typed($1, $3, mLhs) }
3349+
| parenPattern COLON typeWithTypeConstraints %prec paren_pat_colon
3350+
{ let mLhs = lhs parseState
3351+
SynPat.Typed($1, $3, mLhs) }
3352+
3353+
| parenPattern COLON recover
3354+
{ let mColon = rhs parseState 2
3355+
let ty = SynType.FromParseError(mColon.EndRange)
3356+
SynPat.Typed($1, ty, unionRanges $1.Range mColon) }
33473357

33483358
| attributes parenPattern %prec paren_pat_attribs
33493359
{ let mLhs = lhs parseState
@@ -5094,15 +5104,20 @@ topTypeWithTypeConstraints:
50945104
// nb. it doesn't matter where the constraints go in the structure of the type.
50955105
SynType.WithGlobalConstraints(ty, List.rev $3, lhs parseState), arity }
50965106

5097-
opt_topReturnTypeWithTypeConstraints:
5098-
|
5099-
{ None }
5107+
opt_topReturnTypeWithTypeConstraints:
5108+
|
5109+
{ None }
5110+
5111+
| COLON topTypeWithTypeConstraints
5112+
{ let mColon = rhs parseState 1
5113+
let ty, arity = $2
5114+
let arity = (match arity with SynValInfo([], rmdata)-> rmdata | _ -> SynInfo.unnamedRetVal)
5115+
Some (Some mColon, SynReturnInfo((ty, arity), rhs parseState 2)) }
51005116

5101-
| COLON topTypeWithTypeConstraints
5102-
{ let mColon = rhs parseState 1
5103-
let ty, arity = $2
5104-
let arity = (match arity with SynValInfo([], rmdata)-> rmdata | _ -> SynInfo.unnamedRetVal)
5105-
Some (Some mColon, SynReturnInfo((ty, arity), rhs parseState 2)) }
5117+
| COLON recover
5118+
{ let mColon = rhs parseState 1
5119+
let ty, arity = SynType.FromParseError(mColon.EndRange), SynInfo.unnamedRetVal
5120+
Some (Some mColon, SynReturnInfo((ty, arity), mColon.EndRange)) }
51065121

51075122
topType:
51085123
| topTupleType RARROW topType
@@ -5136,31 +5151,61 @@ topTupleTypeElements:
51365151
[ SynTupleTypeSegment.Type t, Some argInfo ] }
51375152

51385153
topAppType:
5139-
| attributes appType COLON appType
5140-
{ match $2 with
5141-
| SynType.LongIdent(SynLongIdent([id], _, _)) ->
5142-
let m = rhs2 parseState 1 4
5143-
SynType.SignatureParameter($1, false, Some id, $4, m), SynArgInfo($1, false, Some id)
5144-
| _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) }
5145-
5146-
| attributes QMARK ident COLON appType
5147-
{ let m = rhs2 parseState 1 5
5148-
SynType.SignatureParameter($1, true, Some $3, $5, m), SynArgInfo($1, true, Some $3) }
5149-
5150-
| attributes appType
5151-
{ let m = rhs2 parseState 1 2
5152-
SynType.SignatureParameter($1, false, None, $2, m), SynArgInfo($1, false, None) }
5153-
5154-
| appType COLON appType
5155-
{ match $1 with
5156-
| SynType.LongIdent(SynLongIdent([id], _, _)) ->
5157-
let m = rhs2 parseState 1 3
5158-
SynType.SignatureParameter([], false, Some id, $3, m), SynArgInfo([], false, Some id)
5159-
| _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) }
5160-
5161-
| QMARK ident COLON appType
5162-
{ let m = rhs2 parseState 1 4
5163-
SynType.SignatureParameter([], true, Some $2, $4, m), SynArgInfo([], true, Some $2) }
5154+
| attributes appType COLON appType
5155+
{ match $2 with
5156+
| SynType.LongIdent(SynLongIdent([id], _, _)) ->
5157+
let m = unionRanges (rhs parseState 1) $4.Range
5158+
SynType.SignatureParameter($1, false, Some id, $4, m), SynArgInfo($1, false, Some id)
5159+
| _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) }
5160+
5161+
| attributes appType COLON recover
5162+
{ match $2 with
5163+
| SynType.LongIdent(SynLongIdent([id], _, _)) ->
5164+
let mColon = rhs parseState 2
5165+
let m = unionRanges (rhs parseState 1) mColon
5166+
let ty = SynType.FromParseError(mColon.EndRange)
5167+
SynType.SignatureParameter($1, false, Some id, ty, m), SynArgInfo($1, false, Some id)
5168+
| _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) }
5169+
5170+
| attributes QMARK ident COLON appType
5171+
{ let m = unionRanges (rhs parseState 1) $5.Range
5172+
SynType.SignatureParameter($1, true, Some $3, $5, m), SynArgInfo($1, true, Some $3) }
5173+
5174+
| attributes QMARK ident COLON recover
5175+
{ let mColon = rhs parseState 4
5176+
let m = unionRanges (rhs parseState 1) mColon
5177+
let ty = SynType.FromParseError(mColon.EndRange)
5178+
SynType.SignatureParameter($1, true, Some $3, ty, m), SynArgInfo($1, true, Some $3) }
5179+
5180+
| attributes appType
5181+
{ let m = unionRanges (rhs parseState 1) $2.Range
5182+
SynType.SignatureParameter($1, false, None, $2, m), SynArgInfo($1, false, None) }
5183+
5184+
| appType COLON appType
5185+
{ match $1 with
5186+
| SynType.LongIdent(SynLongIdent([id], _, _)) ->
5187+
let m = unionRanges (rhs parseState 1) $3.Range
5188+
SynType.SignatureParameter([], false, Some id, $3, m), SynArgInfo([], false, Some id)
5189+
| _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) }
5190+
5191+
| appType COLON recover
5192+
{ match $1 with
5193+
| SynType.LongIdent(SynLongIdent([id], _, _)) ->
5194+
let mColon = rhs parseState 2
5195+
let m = unionRanges $1.Range mColon
5196+
let ty = SynType.FromParseError(mColon.EndRange)
5197+
SynType.SignatureParameter([], false, Some id, ty, m), SynArgInfo([], false, Some id)
5198+
| _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) }
5199+
5200+
| QMARK ident COLON appType
5201+
{ let m = unionRanges (rhs parseState 1) $4.Range
5202+
SynType.SignatureParameter([], true, Some $2, $4, m), SynArgInfo([], true, Some $2) }
5203+
5204+
| QMARK ident COLON recover
5205+
{ let mColon = rhs parseState 3
5206+
let m = unionRanges (rhs parseState 1) mColon
5207+
let ty = SynType.FromParseError(mColon.EndRange)
5208+
SynType.SignatureParameter([], true, Some $2, ty, m), SynArgInfo([], true, Some $2) }
51645209

51655210
| appType
51665211
{ $1, SynArgInfo([], false, None) }

tests/fsharpqa/Source/Diagnostics/NONTERM/tuplewithlazy01.fs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
// #Regression #Diagnostics
22
// Regression test for DevDiv:64339
33
// Note that the bug still repros in CHK/DBG bits - we will knownfail it
4-
//<Expects status="error" span="(10,25-10,29)" id="FS0010">Unexpected keyword 'lazy' in type definition$</Expects>
5-
//<Expects status="error" span="(10,8-10,9)" id="FS0583">Unmatched '\('$</Expects>
6-
//<Expects status="error" span="(13,29-13,33)" id="FS0010">Unexpected keyword 'lazy'$</Expects>
7-
//<Expects status="error" span="(13,9-13,10)" id="FS0583">Unmatched '\('$</Expects>
4+
//<Expects status="error" span="(8,25-8,29)" id="FS0010">Unexpected keyword 'lazy' in type definition$</Expects>
5+
//<Expects status="error" span="(11,29-11,33)" id="FS0010">Unexpected keyword 'lazy'$</Expects>
86

97
// 5 elements -> ok
108
type Ok(a, b, c, d, e : lazy<int>) = class end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Module
2+
3+
(fun i:)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/Lambda/Param - Missing type 01.fs", false,
4+
QualifiedNameOfFile Module, [], [],
5+
[SynModuleOrNamespace
6+
([Module], false, NamedModule,
7+
[Expr
8+
(Paren
9+
(FromParseError
10+
(Lambda
11+
(false, false,
12+
SimplePats
13+
([Id (i, None, false, false, false, (3,5--3,6))],
14+
(3,5--3,6)),
15+
ArbitraryAfterError ("anonLambdaExpr4", (3,6--3,6)),
16+
Some
17+
([Named (SynIdent (i, None), false, None, (3,5--3,6))],
18+
ArbitraryAfterError ("anonLambdaExpr4", (3,6--3,6))),
19+
(3,1--3,6), { ArrowRange = None }), (3,1--3,6)),
20+
(3,0--3,1), Some (3,7--3,8), (3,0--3,8)), (3,0--3,8))],
21+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
22+
(1,0--3,8), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
23+
{ ConditionalDirectives = []
24+
CodeComments = [] }, set []))
25+
26+
(3,6)-(3,7) parse error Unexpected symbol ':' in lambda expression. Expected '->' or other token.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Module
2+
3+
(fun i: -> ())
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/Lambda/Param - Missing type 02.fs", false,
4+
QualifiedNameOfFile Module, [], [],
5+
[SynModuleOrNamespace
6+
([Module], false, NamedModule,
7+
[Expr
8+
(Paren
9+
(FromParseError
10+
(Lambda
11+
(false, false,
12+
SimplePats
13+
([Id (i, None, false, false, false, (3,5--3,6))],
14+
(3,5--3,6)),
15+
ArbitraryAfterError ("anonLambdaExpr4", (3,6--3,6)),
16+
Some
17+
([Named (SynIdent (i, None), false, None, (3,5--3,6))],
18+
ArbitraryAfterError ("anonLambdaExpr4", (3,6--3,6))),
19+
(3,1--3,6), { ArrowRange = None }), (3,1--3,6)),
20+
(3,0--3,1), Some (3,13--3,14), (3,0--3,14)), (3,0--3,14))],
21+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
22+
(1,0--3,14), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
23+
{ ConditionalDirectives = []
24+
CodeComments = [] }, set []))
25+
26+
(3,6)-(3,7) parse error Unexpected symbol ':' in lambda expression. Expected '->' or other token.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Module
2+
3+
(fun (i:) -> ())
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/Lambda/Param - Missing type 03.fs", false,
4+
QualifiedNameOfFile Module, [], [],
5+
[SynModuleOrNamespace
6+
([Module], false, NamedModule,
7+
[Expr
8+
(Paren
9+
(Lambda
10+
(false, false,
11+
SimplePats
12+
([Typed
13+
(Id (i, None, false, false, false, (3,6--3,7)),
14+
FromParseError (3,8--3,8), (3,6--3,8))], (3,5--3,9)),
15+
Const (Unit, (3,13--3,15)),
16+
Some
17+
([Paren
18+
(Typed
19+
(Named
20+
(SynIdent (i, None), false, None, (3,6--3,7)),
21+
FromParseError (3,8--3,8), (3,6--3,8)), (3,5--3,9))],
22+
Const (Unit, (3,13--3,15))), (3,1--3,15),
23+
{ ArrowRange = Some (3,10--3,12) }), (3,0--3,1),
24+
Some (3,15--3,16), (3,0--3,16)), (3,0--3,16))],
25+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
26+
(1,0--3,16), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
27+
{ ConditionalDirectives = []
28+
CodeComments = [] }, set []))
29+
30+
(3,8)-(3,9) parse error Unexpected symbol ')' in pattern
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Module
2+
3+
(fun (i:, j) -> ())
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
ImplFile
2+
(ParsedImplFileInput
3+
("/root/Lambda/Param - Missing type 04.fs", false,
4+
QualifiedNameOfFile Module, [], [],
5+
[SynModuleOrNamespace
6+
([Module], false, NamedModule,
7+
[Expr
8+
(Paren
9+
(Lambda
10+
(false, false,
11+
SimplePats
12+
([Typed
13+
(Id (i, None, false, false, false, (3,6--3,7)),
14+
FromParseError (3,8--3,8), (3,6--3,8));
15+
Id (j, None, false, false, false, (3,10--3,11))],
16+
(3,5--3,12)), Const (Unit, (3,16--3,18)),
17+
Some
18+
([Paren
19+
(Tuple
20+
(false,
21+
[Typed
22+
(Named
23+
(SynIdent (i, None), false, None, (3,6--3,7)),
24+
FromParseError (3,8--3,8), (3,6--3,8));
25+
Named
26+
(SynIdent (j, None), false, None, (3,10--3,11))],
27+
(3,6--3,11)), (3,5--3,12))],
28+
Const (Unit, (3,16--3,18))), (3,1--3,18),
29+
{ ArrowRange = Some (3,13--3,15) }), (3,0--3,1),
30+
Some (3,18--3,19), (3,0--3,19)), (3,0--3,19))],
31+
PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None,
32+
(1,0--3,19), { LeadingKeyword = Module (1,0--1,6) })], (true, true),
33+
{ ConditionalDirectives = []
34+
CodeComments = [] }, set []))
35+
36+
(3,8)-(3,9) parse error Unexpected symbol ',' in pattern

0 commit comments

Comments
 (0)